seata事務(wù)隔離

官網(wǎng)解釋
https://seata.io/zh-cn/docs/user/appendix/isolation.html
看官網(wǎng)之前一定要分清官網(wǎng)中說(shuō)的全局事務(wù)和本地事務(wù),本地事務(wù)就是平時(shí)開(kāi)發(fā)的時(shí)候
用@Transactional標(biāo)注的方法,執(zhí)行多個(gè)sql保證統(tǒng)一提交,利用的是數(shù)據(jù)庫(kù)自身的事務(wù)
全局事務(wù)就是seata自帶的事務(wù),跨服務(wù)的事務(wù),這兩個(gè)分不清理解不好隔離,
在debug的時(shí)候,不要debug全部線程,因?yàn)橛行奶絥acos,超過(guò)30秒就下線了,就會(huì)發(fā)生Feign找不到服務(wù)

image.png

1.本地事務(wù)修改了全局事務(wù)的數(shù)據(jù),回滾問(wèn)題
image.png

T1為全局事務(wù),T2為本地事務(wù)
T1修改庫(kù)存之后,還要生成訂單,當(dāng)生成訂單的時(shí)候發(fā)生異常,但是T2本地事務(wù)不受全局事務(wù)的限制直接修改了庫(kù)存,T1回滾庫(kù)存服務(wù)的時(shí)候就異常,會(huì)一直重試直到超時(shí).超時(shí)時(shí)間通過(guò)配置
server.maxRollbackRetryTimeout=-1 -1代表永不超時(shí)
測(cè)試
T1事務(wù)


image.png

T2調(diào)用庫(kù)存服務(wù)修改庫(kù)存數(shù)據(jù)


image.png

全局事務(wù)服務(wù)發(fā)起調(diào)用
image.png

T1修改庫(kù)存服務(wù)之前剩余80
image.png

T1調(diào)用訂單服務(wù)時(shí)debug,是要拋出異常的


image.png

T1修改庫(kù)存剩余78,雖然T1此時(shí)沒(méi)有提交全局事務(wù),但是庫(kù)存數(shù)據(jù)庫(kù)已經(jīng)提交(AT模式特性)


image.png

T2事務(wù)
修改庫(kù)存(此時(shí)T1還沒(méi)有提交,debug阻塞在生成訂單服務(wù))
image.png

數(shù)據(jù)庫(kù)修改數(shù)據(jù)由78修改76


image.png

T1服務(wù)debug放開(kāi),因?yàn)閽伋霎惓?通過(guò)TC通知庫(kù)存服務(wù)重試回滾數(shù)據(jù),因?yàn)樾薷暮蟮臄?shù)據(jù)為78,回滾的是判斷當(dāng)前數(shù)據(jù)是否為78,但是當(dāng)前已經(jīng)被T2修改未76,一直重試回滾,當(dāng)我們手動(dòng)的修改數(shù)據(jù)庫(kù)為78時(shí),具備回滾條件,將數(shù)據(jù)修改為T(mén)1事務(wù)之前的數(shù)據(jù)80
image.png
2.兩個(gè)全局事務(wù)

示例1提到了,本地事務(wù)可以修改全局事務(wù)的數(shù)據(jù),那能不能像本地事務(wù)那樣阻塞住,T2等T1全局事務(wù)提交后,再繼續(xù)執(zhí)行T2呢,答案是可以的,只要將T2升級(jí)為全局事務(wù),只是標(biāo)注
@GlobalTransactional就可以了
在本地測(cè)試的時(shí)候,記著把垃圾數(shù)據(jù)清理,比如lock_table表,undolog表的數(shù)據(jù)都清理一下,不清理會(huì)提示數(shù)據(jù)被鎖的給錯(cuò)誤信息
當(dāng)T2標(biāo)注@GlobalTransactional就會(huì)提示錯(cuò)誤


image.png

超時(shí)了,也是通過(guò)配置實(shí)現(xiàn)的,重試30次,每次10毫秒
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
找了一下重試超時(shí)的源碼,像這種一定是while(true)或者for(;;)加異常退出的方式
io.seata.rm.datasource.exec.LockRetryController#sleep

3.T1T2都為全局事務(wù),T2為全局讀

上面兩個(gè)例子是寫(xiě)隔離,那讀隔離呢
AT模式,都是先將數(shù)據(jù)commit,在回滾的時(shí)候才會(huì)把數(shù)據(jù)通過(guò)補(bǔ)償?shù)姆绞交謴?fù),
如果T2為全局事務(wù)讀取庫(kù)存數(shù)據(jù),查詢語(yǔ)句為select * from stock where id = 1,
當(dāng)T1全局事務(wù)還沒(méi)有提交的時(shí)候,但是庫(kù)存其實(shí)已經(jīng)修改了,T2讀取的也是修改之后的數(shù)據(jù)
其實(shí)希望的是,T1全局事務(wù)沒(méi)有提交,即使庫(kù)存數(shù)據(jù)已經(jīng)修改了,還想讀取未修改之前的數(shù)據(jù),
官網(wǎng)上提到了 使用 for update的方式,這里就不詳細(xì)的說(shuō)明了,在git上都有,postman的請(qǐng)求也會(huì)發(fā)到git上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容