FolkMQ 提供了二段式提交的事務提交的機制(TCC 模型)。允許生產者在發送消息時綁定到一個事務中並接收事務的管理,以確保消息的原子性(要麼全成功,要麼全失敗)。在 FolkMQ 中,事務是通過 MqTransaction 接口實現管理的。一般是通過:
- 新建事務:在產生者端,可以通過調用
MqTransaction tran = client.newTransaction()
新建一個事務。後續的消息發送與此事務綁定。綁定的消息,即參與此事務;沒綁定的消息,則照舊。 - 發送消息(T):接下來的事務中,嘗試發送消息。此時,中間件會把消息放在一個事務中轉隊列裏。
- 提交事務(C):如果所有消息都發送成功了,就通過
tran.commit()
方法提交事務。此時,中間件把事務相關消息從事務中轉隊列取出,並轉到派發隊列。 - 回滾事務(C):通過
try catch
,如果有某一條消息發送異常了。就通過tran.rollback()
方法回滾事務,即所有消息全部取消。此時,中間件把事務相關消息從事務中轉隊列刪掉。
發送事務消息:
//發送事務消息
MqTransaction tran = client.newTransaction();
try {
//同步
client.publish("demo", new MqMessage("demo1").attr("orderId","1").transaction(tran));
client.publish("demo", new MqMessage("demo2").attr("orderId","1").transaction(tran));
//異步,也行!
client.publishAsync("demo", new MqMessage("demo3").attr("orderId","1").transaction(tran));
client.publishAsync("demo", new MqMessage("demo4").attr("orderId","1").transaction(tran));
tran.commit();
} catch (Throwable e) {
tran.rollback();
}
FolkMQ 的服務端事務處理,是基於專屬的"事務中轉隊列"實現(支持快照持久化)。它可以保證在事務中的消息,要麼全部成功,要麼全部失敗。而且,當客戶端沒有提交二次確認時(偶爾會有網絡原因),超過60秒後,會發起反向“回查”。要實現更“周密”的事務處理,客戶端還需要實現回查處理。一般在客戶端初始化時,或者連接建立後配置事務回查處理:
MqClient client = FolkMQ.createClient("folkmq://127.0.0.1:18602")
.nameAs("demoapp") //一般用當前應用名
.connect();
client.transactionCheckback(m->{
if("1".equals(m.getAttr("orderId"))) {
m.acknowledge(true);
}
});
FolkMQ 的事務機制,並且不會對性能有影響,與非事務消息性能沒什麼差別。