seata AT模式:
優點:
業務無侵入的
限制:
底層的數據庫需要是支持事物的,比如msyql innodb
1先要獲得數據庫的連接connection,返回自定義的連接,自定義的連接在目標方法執行完之後,先進入等待狀態,等事務管理者的最後通知再提交或回滾
2根據業務方法上面的註解判斷本地事務操作,如果是第一個,就要負責通知創建事務組,並添加自己的事物到事務組中
如果是最後一個,就要負責通知事務管理者,進行最後的裁決
3本地事務執行之後,會根據執行的結果,向事務管理者註冊本地的狀態,成功就提交,失敗就回滾
4事物管理者收到事務結束的通知後,進行裁決,判斷當前事物組中的所有事物是否有回滾狀態的,有就通知事務組裏面的所有本地事務進行回滾,否則,提交
server1
@Service
public class DemoService {
@Autowired
private DemoDao demoDao;
@Lbtransactional(isStart = true)
@Transactional
public void test() {
demoDao.insert("server1");
HttpClient.get("http://localhost:8082/server2/test");
// int i = 100/0;
}
}
server2
@Service
public class DemoService {
@Autowired
private DemoDao demoDao;
@Lbtransactional(isEnd = true)
@Transactional
public void test() {
demoDao.insert("server2");
}
}
運行結果:
server1經歷的流程:
1創建事務組
2創建事務
3添加事務
4接受數據:{"groupId":"32bed63a-1ddf-4839-9783-6e92ba87c228","command":"commit"}
5接收command:commit
server2經歷的流程:
1創建事務
2添加事務
3接受數據:{"groupId":"32bed63a-1ddf-4839-9783-6e92ba87c228","command":"commit"}
4接收command:commit
如果將server1中的註釋去掉,手動製造一個除數爲零的異常,重新請求,數據庫表中將沒有一條數據被插入
server1經歷的流程:
1創建事務組
2創建事務
3添加事務
java.lang.ArithmeticException: / by zero
4接受數據:{"groupId":"ed2bb237-872e-4690-a21a-e7e0a93f7036","command":"rollback"}
5接收command:rollback
server2經歷的流程:
1創建事務
2添加事務
3接受數據:{"groupId":"ed2bb237-872e-4690-a21a-e7e0a93f7036","command":"rollback"}
4接收command:rollback
參考資源:https://www.bilibili.com/video/av64870581/?p=9&t=3242
tips:
jvm參數:
提示:因爲AOP是基於動態代理生成,如果想要仔細研究生成的代理類長什麼樣,可以設置系統參數-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true,這樣就會保存所有自動生成的代理類(注:生產環境嚴禁使用)。