全域性事務與本地事務的區別應用

2021-07-11 13:31:43 字數 2717 閱讀 2620

全域性事務:

資源管理器管理和協調的事務,可以跨越多個資料庫和程序。資源管理器一般使用 xa 二階段提交協議與「企業資訊系統」(eis) 或資料庫進行互動。 

本地事務:

在單個 eis 或資料庫的本地並且限制在單個程序內的事務。本地事務不涉及多個資料**。 

在hibernate配置檔案中有這麼兩種配置方式:

1.如果使用的是本地事務(jdbc事務)

thread,這個是我們常用的選項,只針對乙個資料庫進行操作,也就是說只針對乙個事務性資源進行操作.

2. 如果使用的是全域性事務(jta事務)

jta以前我們學習的事務型別都屬於本地事務。 jta(全域性事務)和thread(本地事務)有什麼區別呢?在某些應用場合,只能使用全域性事務,比如: 

有兩個資料庫: 

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,那麼全域性事務就認為你這個事務是失敗的,它就會進行回滾,回滾的時候,哪怕你的第二條語句在第一次提交的時候是成功的,它在第二次提交的時候也會回滾,那麼第一次的更改也會恢復到之前的狀態,這就是二次提交協議。(可以檢視一下資料庫方面的文件來了解二次提交協議)

全域性事務與本地事務

全域性事務 資源管理器管理和協調的事務,可以跨越多個資料庫和程序。資源管理器一般使用 xa 二階段提交協議與 企業資訊系統 eis 或資料庫進行互動。本地事務 在單個 eis 或資料庫的本地並且限制在單個程序內的事務。本地事務不涉及多個資料 在hibernate配置檔案中有這麼兩種配置方式 1.如果...

本地事務 全域性事務 分布式事務

本地事務 事務隔離級別 select tx isolation tx isolation repeatable read 1 row in set 0.00 sec 開啟事務 執行緒1執行如下。use order db begin update orders set order money orde...

Redis事務與MySQL事務的區別

1.想著 在springboot事務中,第一步insert mysql 第二步 更新到redis中 transactional rollbackfor public void addchannel meschannelvo meschannelvo 3.測試事務回滾 int i null int i...