全局事务与本地事务的区别应用(从代码方面来探讨的)
生活随笔
收集整理的這篇文章主要介紹了
全局事务与本地事务的区别应用(从代码方面来探讨的)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
全局事務:資源管理器管理和協調的事務,可以跨越多個數據庫和進程。資源管理器一般使用 XA 二階段提交協議與“企業信息系統”(EIS) 或數據庫進行交互。?
本地事務:在單個 EIS 或數據庫的本地并且限制在單個進程內的事務。本地事務不涉及多個數據來源。?
有兩個數據庫:
1.mysql 2.oracle? 現在有個業務需求--轉賬
step 1> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
step 2> update oracle_table set amount=amount+xx where id=bbb 加錢,假設是在oracle數據庫扣錢的。
現在怎么確保兩個語句在同一個事務里執行呢?
以前在JDBC里是這樣做
connection = mysql 連接mysql
connection.setAutoCommit(false);? 不自動提交
1> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
2> update oracle_table set amount=amount+xx where id=bbb? 發生在oracle數據庫
connection.commit();
執行這兩條語句,然后通過connection對象提交事務.我們這樣子做只能確保這兩個語句在同一個數據庫mysql里面實現在同一個事務里執行。 但是問題是我們現在是要連接到oracle數據庫,是不是需要connection2啊?
connection = mysql 連接mysql
connection2 = oracle 連接oracle
connection.setAutoCommit(false);? 不自動提交
1> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
2> update oracle_table set amount=amount+xx where id=bbb? 發生在oracle數據庫
connection.commit();
connection2.setAutoCommit(false);
connection2.commit();
事務只能在一個connection里打開,并且確保兩條語句都在該connection里執行,這樣才能讓兩條語句在同一事務里執行,現在問題就在于connection2是連接到oracle數據庫的,那么connection2再開事務有意義嗎?它能確保嗎?不能,所以在這種情況下就只能使用全局事務了。
這種情況下用普通JDBC操作是滿足不了這個業務需求的,這種業務需求只能使用全局事務,本地事務是無法支持我們的操作的,因為這時候,事務的生命周期不應該局限于connection對象的生命周期范圍
全局事務怎么做呢?
JPA.getUserTransaction().begin();????? 首先要全局事務的API,不需要我們編寫,通常容器已經提供給我們了,我們只需要begin一下
connection = mysql 連接mysql
connection2 = oracle 連接oracle
connection--> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
connection2--> update oracle_table set amount=amount+xx where id=bbb 發生在oracle數據庫
JPA.getUserTransaction().commit();
那么它是怎么知道事務該提交還是回滾呢?
這時候它使用了二次提交協議。二次提交協議簡單說就這樣:如果你先執行第一條語句,執行的結果先預提交到數據庫,預提交到數據庫了,數據庫會執行這條語句,然后返回一個執行的結果,這個結果假如我們用布爾值表示的話,成功就是true,失敗就是false.然后把執行的結果放入一個(假設是List)對象里面去,接下來再執行第二條語句,執行完第二條語句之后(也是預處理,數據庫不會真正實現數據的提交,只是說這條語句送到數據庫里面,它模擬下執行,給你返回個執行的結果),假如這兩條語句的執行結果在List里面都是true的話,那么這個事務就認為語句是成功的,這時候全局事務就會提交。二次提交協議,數據庫在第一次提交這個語句時,只會做預處理,不會發生真正的數據改變,當我們在全局事務提交的時候,這時候發生了第二次提交,那么第二次提交的時候才會真正的發生數據的改動。
???如果說在執行這兩條語句中,有一個出錯了,那么List集合里就有個元素為false,那么全局事務就認為你這個事務是失敗的,它就會進行回滾,回滾的時候,哪怕你的第二條語句在第一次提交的時候是成功的,它在第二次提交的時候也會回滾,那么第一次的更改也會恢復到之前的狀態,這就是二次提交協議。(可以查看一下數據庫方面的文檔來了解二次提交協議) 與50位技術專家面對面20年技術見證,附贈技術全景圖
本地事務:在單個 EIS 或數據庫的本地并且限制在單個進程內的事務。本地事務不涉及多個數據來源。?
在Hibernate配置文件中有這么兩種配置方式:
1.如果使用的是本地事務(jdbc事務)
<property name="hibernate.current_session_context_class">thread</property>,這個是我們常用的選項,只針對一個數據庫進行操作,也就是說只針對一個事務性資源進行操作.
2. 如果使用的是全局事務(jta事務)
<property name="hibernate.current_session_context_class">jta</property> ???
有兩個數據庫:
1.mysql 2.oracle? 現在有個業務需求--轉賬
step 1> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
step 2> update oracle_table set amount=amount+xx where id=bbb 加錢,假設是在oracle數據庫扣錢的。
現在怎么確保兩個語句在同一個事務里執行呢?
以前在JDBC里是這樣做
connection = mysql 連接mysql
connection.setAutoCommit(false);? 不自動提交
1> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
2> update oracle_table set amount=amount+xx where id=bbb? 發生在oracle數據庫
connection.commit();
執行這兩條語句,然后通過connection對象提交事務.我們這樣子做只能確保這兩個語句在同一個數據庫mysql里面實現在同一個事務里執行。 但是問題是我們現在是要連接到oracle數據庫,是不是需要connection2啊?
connection = mysql 連接mysql
connection2 = oracle 連接oracle
connection.setAutoCommit(false);? 不自動提交
1> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
2> update oracle_table set amount=amount+xx where id=bbb? 發生在oracle數據庫
connection.commit();
connection2.setAutoCommit(false);
connection2.commit();
事務只能在一個connection里打開,并且確保兩條語句都在該connection里執行,這樣才能讓兩條語句在同一事務里執行,現在問題就在于connection2是連接到oracle數據庫的,那么connection2再開事務有意義嗎?它能確保嗎?不能,所以在這種情況下就只能使用全局事務了。
這種情況下用普通JDBC操作是滿足不了這個業務需求的,這種業務需求只能使用全局事務,本地事務是無法支持我們的操作的,因為這時候,事務的生命周期不應該局限于connection對象的生命周期范圍
全局事務怎么做呢?
JPA.getUserTransaction().begin();????? 首先要全局事務的API,不需要我們編寫,通常容器已經提供給我們了,我們只需要begin一下
connection = mysql 連接mysql
connection2 = oracle 連接oracle
connection--> update mysql_table set amount=amount-xx where id=aaa 發生扣錢,假設是在mysql數據庫扣錢的。
connection2--> update oracle_table set amount=amount+xx where id=bbb 發生在oracle數據庫
JPA.getUserTransaction().commit();
那么它是怎么知道事務該提交還是回滾呢?
這時候它使用了二次提交協議。二次提交協議簡單說就這樣:如果你先執行第一條語句,執行的結果先預提交到數據庫,預提交到數據庫了,數據庫會執行這條語句,然后返回一個執行的結果,這個結果假如我們用布爾值表示的話,成功就是true,失敗就是false.然后把執行的結果放入一個(假設是List)對象里面去,接下來再執行第二條語句,執行完第二條語句之后(也是預處理,數據庫不會真正實現數據的提交,只是說這條語句送到數據庫里面,它模擬下執行,給你返回個執行的結果),假如這兩條語句的執行結果在List里面都是true的話,那么這個事務就認為語句是成功的,這時候全局事務就會提交。二次提交協議,數據庫在第一次提交這個語句時,只會做預處理,不會發生真正的數據改變,當我們在全局事務提交的時候,這時候發生了第二次提交,那么第二次提交的時候才會真正的發生數據的改動。
???如果說在執行這兩條語句中,有一個出錯了,那么List集合里就有個元素為false,那么全局事務就認為你這個事務是失敗的,它就會進行回滾,回滾的時候,哪怕你的第二條語句在第一次提交的時候是成功的,它在第二次提交的時候也會回滾,那么第一次的更改也會恢復到之前的狀態,這就是二次提交協議。(可以查看一下數據庫方面的文檔來了解二次提交協議) 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的全局事务与本地事务的区别应用(从代码方面来探讨的)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金寨今天有上电瓶车牌照的吗?
- 下一篇: 200汽车车架号查询出来与汽车不符是什么