集成 spring-cloud-starter-alibaba-seata @GlobalTransactional 失效的問題


問題復現

設備健康 business 服務調用 admin 服務,前者制造異常並成功回滾,后者未出現異常但是並未回滾

 

源碼分析

加上全局事務注解之后會走 io.seata.tm.api.TransactionalTemplate#execute 方法做事務相關處理;

該方法主要分為5個步驟:

第一步:獲取當前全局事務

第二步:開啟全局事務,並處理業務

第三步:業務異常則回滾事務

第四步:業務正常則提交事務

第五步:清理

 

 

問題定位

這次問題出現在第一步,從上下文獲取當前全局事務

  

business 服務是全局事務的第一段,拿不到 xid 理所應當,會創建一個全局事務對象

 

admin 服務是全局事務的第二段,理論上 business 會把 xid 傳遞給 admin;

事實上發現 RootContext 並未獲取到 xid,從而 admin 也創建一個全局事務對象;

這樣一來,business 和 admin 各自創建了自己的全局事務,xid 不同,導致 business 能夠正常回滾,admin 卻提交了自己的事務。

 

個人猜測是 request 把 xid 丟失了,沒有傳遞給下游;

果不其然 com.alibaba.cloud.seata.web.SeataHandlerInterceptor 打斷點,卻始終未進斷點

 

這里能斷定 com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration 未生效;

由於使用了 @ConditionalOnWebApplication,必須是 web mvc 項目才生效。

 

web mvc 自動配置 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration 前提是沒有 

org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport 這個 bean

 

所以罪魁禍首是 WebMvcConfigurationSupport

總結

項目總如果使用了 WebMvcConfigurationSupport 會直接導致 WebMvcConfigurer 不生效,那么需要將 SeataHandlerInterceptor 手動放到攔截器鏈路中;

個人建議實現 WebMvcConfigurer 而不是繼承 WebMvcConfigurationSupport,這樣的話一切都不會有問題。

seata 常見問題:http://seata.io/zh-cn/docs/overview/faq.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM