本次發布主提供多庫和微服務事務支持,使用了 BeetlSQL 的自帶的 Saga 實現
Saga文檔
Maven
<dependency> <groupId>com.ibeetl</groupId> <artifactId>beetlsql</artifactId> <version>3.2.0-RELEASE</version></dependency>
Saga 初期是長事務的解決方案,微服務流行後也可以為微服務提供事務解決方案。不同於傳統的資料庫事務或者 2 階段提交,必須·依賴於資料庫系統實現 ACID 事務,Saga 不依賴於特定系統(實際上也不可能讓所有系統實現 ACID,比如 Redis,Mongdb),只要求特定系統能提供補償操作,在出錯的時候能執行補償操作即可。因此可以很方便用在現代的微服務架構中。
一個長事務的例子,如訂購電影票,分為選座位和支付倆個步驟。用戶可能會花好幾分鐘才能能完成。另一個例子是下單旅遊產品,需要酒店,飛機,旅行社各個系統協作。 關於Saga,我認為最好的文章是 https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/saga/saga,因為他即告訴你什麼是Saga。也告訴你Saga不完美的地方。
因此 Saga 的核心是補償操作以及執行這些操作的任務的管理。下面列舉了一些目前我認為的現在一些 Saga 框架實現的缺點
BeetlSQL 的 Saga 實現試圖解決上述問題。讓微服務編程變得跟簡單。
單系統多庫 Saga 事務
@Testpublic void simple(){ SagaContext sagaContext = SagaContext.sagaContextFactory.current(); UserMapper userMapper = sqlManager.getMapper(UserMapper.class); long count = sqlManager.allCount(User.class); try{ sagaContext.start() User user = new User(); user.setName("abc"); userMapper.insert(user); //根據名字hash入不同資料庫 User user2 = new User(); user2.setName("efg"); userMapper.insert(user2); if(1==1){ throw new RuntimeException("模擬異常"); } sagaContext.commit(); }catch(RuntimeException ex){ sagaContext.rollback(); } long afterCount = sqlManager.allCount(User.class); Assert.assertEquals(count,afterCount);}
微服務Saga事務,採用同樣的編程方式
SagaContext sagaContext = SagaContext.sagaContextFactory.current();try { sagaContext.start(gid); //模擬調用倆個微服務,訂單和用戶 rest.postForEntity(orderAddUrl, null,String.class, paras); rest.postForEntity(userBalanceUpdateUrl, null,String.class, paras); if (1 == 1) { throw new RuntimeException("模擬失敗,查詢saga-server 看效果"); }} catch (Exception e) { sagaContext.rollback(); return e.getMessage();}
BeetlSQL 的目標是提供開發高效,維護高效,運行高效的資料庫訪問框架,在一個系統多個庫的情況下,提供一致的編寫代碼方式。支持如下數據平臺
閱讀文檔 源碼和例子