.Net Core with 微服务 - 使用 AgileDT 快速实现基于可靠消息的分布式事务
前面對于分布式事務(wù)也講了好幾篇了(可靠消息最終一致性分布式事務(wù) - TCC分布式事務(wù) - 2PC、3PC
https://github.com/kklldog/AgileDT 開源不易,大家多多 ???
回顧
前面一篇文章(可靠消息最終一致性 )我們詳細介紹了基于可靠消息的分布式事務(wù)。為了更好的理解 AgileDT 的代碼,我們還是有必要簡單的來回顧下。
該方案總體流程上可分為以下步驟:
主動方在真正的業(yè)務(wù)開始前先向可靠消息服務(wù)發(fā)送一個“待確認”的消息
可靠消息服務(wù)收到待確認消息后持久化消息到數(shù)據(jù)庫
如果以上操作成功則主動方開始真正的業(yè)務(wù),如果失敗則直接放棄執(zhí)行業(yè)務(wù)
如果業(yè)務(wù)執(zhí)行成功則發(fā)送“確認”消息給可靠消息服務(wù),如果執(zhí)行失敗則發(fā)送“取消”給可靠消息服務(wù)。
如果可靠消息服務(wù)收到“確認”消息則更新數(shù)據(jù)庫里的消息記錄的狀態(tài)為“待發(fā)送”,如果收到的消息為“取消”則更新消息狀態(tài)為“已取消”
如果上一步更新的數(shù)據(jù)庫為“待發(fā)送”,那么會開始往MQ投遞消息,并且更改數(shù)據(jù)庫里的消息記錄的狀態(tài)為“已發(fā)送”
上一步往MQ投遞消息成功后,MQ會給被動方推送消息。
被動方收到消息后開始處理業(yè)務(wù)
如果業(yè)務(wù)處理成功,則被動方對MQ進行ACK回復(fù),則這條消息會從MQ內(nèi)移除掉
如果業(yè)務(wù)處理成功,則發(fā)送“已完成”消息給可靠消息服務(wù)
可靠消息服務(wù)收到“已完成”消息后更新數(shù)據(jù)庫消息記錄未“已完成”
廢話不多說了,下面讓我們演示下如何使用 AgileDT 來快速實現(xiàn)一個基于可靠消息的分布式事務(wù)。
以下我們還是以經(jīng)典的訂單下單完成給會員贈送積分的場景來演示。
使用 AgileDT
依賴組件
mysql
rabbitmq
目前支持 mysql 數(shù)據(jù)庫,但是數(shù)據(jù)訪問組件使用的是 freesql 所以后續(xù)要實現(xiàn)支持別的數(shù)據(jù)庫也很簡單。目前框架使用的可靠消息服務(wù)為 rabbitmq 。
運行服務(wù)端
在服務(wù)新建一個數(shù)據(jù)庫并且新建一張表
//?crate?event_message?table?on?mysql create?table?if?not?exists?event_message (event_id?varchar(36)?not?nullprimary?key,biz_msg?varchar(4000)?null,status?enum('Prepare',?'Done',?'WaitSend',?'Sent',?'Finish',?'Cancel')?not?null,create_time?datetime(3)?null,event_name?varchar(255)?null );使用docker-compose運行服務(wù)端
version:?"3"??#?optional?since?v1.27.0 services:agile_dt:image:?"kklldog/agile_dt"ports:-?"5000:5000"environment:-?db:provider=mysql-?db:conn=?Database=agile_dt;Data?Source=192.168.0.115;User?Id=root;Password=mdsd;port=3306-?mq:userName=admin-?mq:password=123456-?mq:host=192.168.0.115-?mq:port=5672安裝客戶端
在主動方跟被動方都需要安裝AgileDT的客戶端庫
Install-Package?AgileDT.Client主動方使用方法
在業(yè)務(wù)數(shù)據(jù)庫添加事務(wù)消息表
修改配置文件
注入 AgileDT 客戶端服務(wù)
實現(xiàn)IEventService方法
處理主動方業(yè)務(wù)邏輯的類需要實現(xiàn)IEventService接口,并且標記那個方法是真正的業(yè)務(wù)方法。AgileDT在啟動的時候會掃描這些類型,并且使用AOP技術(shù)生成代理類,在業(yè)務(wù)方法前后插入對應(yīng)的邏輯來跟可靠消息服務(wù)通訊。這里要注意的幾個地方:
實現(xiàn)IEventService接口
使用DtEventBizMethod注解標記業(yè)務(wù)入口方法
使用DtEventName注解來標記事務(wù)的方法名稱,如果不標記則使用類名
注意:業(yè)務(wù)方法最終一定要使用事務(wù)來同步修改消息表的status字段為done狀態(tài),這個操作框架沒辦法幫你實現(xiàn)
注意:業(yè)務(wù)方法如果失敗請拋出Exception,如果不拋異常框架一律認為執(zhí)行成功
在實現(xiàn)好 IAddOrderService 接口后,你可以像平常一樣使用 IAddOrderService 來注入實現(xiàn)類。比如在 Controller 的構(gòu)造函數(shù)注入進去。因為 AgileDT 在啟動的時候會自動幫你注冊。
注意:IAddOrderService 跟實現(xiàn)類的生命周期是 Scoped 。
被動方使用方法
在業(yè)務(wù)方數(shù)據(jù)庫建表或者在業(yè)務(wù)表上加字段
對于被動方來說這里不是必須要建一個表。但是至少要有個地方來存儲event_id的信息,最簡單的是直接在業(yè)務(wù)主表上加event_id字段。
修改配置文件
注入AgileDT服務(wù)
實現(xiàn)IEventMessageHandler接口
被動方需要接收MQ投遞過來的消息,這些處理類需要實現(xiàn)IEventMessageHandler接口。AgileDT啟動的時候會去掃描這些類,然后跟MQ建立綁定關(guān)系。
這里必須使用DtEventName注解標記需要處理的事件名稱
Reveive 方法必須是冪等的
總結(jié)
通過以上演示,我們快速的實現(xiàn)了一個訂單下單會員贈送積分的服務(wù)??梢钥吹绞褂?AgileDT 可以很快速的實現(xiàn)一個分布式事務(wù)。特別是在實現(xiàn)過一個分布式事務(wù)后,后面實現(xiàn)起來就特別簡單,只要實現(xiàn)幾個接口就可以了。AgileDT 才剛剛起步,希望大家多多支持,多多??? ?,多多 PR 。
https://github.com/kklldog/AgileDT
.Net Core with 微服務(wù) - 可靠消息最終一致性分布式事務(wù)
.Net Core with 微服務(wù) - 分布式事務(wù) - TCC
.Net Core with 微服務(wù) - 分布式事務(wù) - 2PC、3PC
總結(jié)
以上是生活随笔為你收集整理的.Net Core with 微服务 - 使用 AgileDT 快速实现基于可靠消息的分布式事务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 被质疑“在开源社区执行微软意愿”,.NE
- 下一篇: 如何在 ASP.NET Web API