分布式事務 小結


分布式事務 
  如果系統規模較小,數據表都在一個數據庫實例上,上述本地事務方式可以很好地運行,
  但是如果系統規模較大,比如用戶A賬戶表和用戶B賬戶表顯然不會在同一個數據庫實例上,他們往往分布在不同的物理節點上,這時本地事務已經失去用武之地。

分布式事務解決方法 
  兩階段提交(多次節點間的通信,事務時間較長,鎖定資源的時間較長,不適合高並發系統)
消息(最終一致性)
  數據 在一段時間是不一致的,但是最終能夠實現一致性,可以提高並發量,
  比如,現在很多飯店都是小票排號,你點了什么菜,飯點的時候人很多,不能點了菜,馬上就能上菜,但是你已經排上號了,最終都會給你上菜的.這就是最終的一致性. 很顯然這樣能夠提高接待能力.

消息與業務耦合
  Begin transaction
  update A set amount=amount-10000 where userId=1;
  insert into message(userId, amount,status) values(1, 10000, 1);//這里不直接發送消息 是因為如果消息發送了,但是B沒有收到,這條鏈路就斷了
  End transaction
  commit;
定時任務讀取A消息表 發送消息
  當上述事務提交成功后,我們通過實時消息服務將此消息通知用戶B,用戶B處理成功后發送回復成功消息,用戶A收到回復后修改該條消息數據的狀態。
  用戶A收到回復消息,,把消息從消息表中刪除,並插入到消息備份表中,(可用於消息補償)

防止消息的多次投遞. 在B端做冪等控制, 在B端記錄消息的消費情況 
  B端執行的情況的時候,都要先去查詢一下這個消息是否存在,如果存在直接放棄.如果不存在就執行B的加錢操作,然后往消息表里面插入接收到的消息數據.這些操作在一個事務里面

定時任務去檢索消息表,發送消息消費成功回調消息給A

消息與業務解耦 


上述保存消息的方式使得消息數據和業務數據緊耦合在一起,從架構上看不夠優雅,而且容易誘發其他問題。為了解耦,可以采用以下方式。

  1)用戶A在扣款事務提交之前,向實時消息服務請求發送消息,實時消息服務只記錄消息數據,而不真正發送,只有消息發送成功后才會提交事務;

  2)當用戶A扣款事務被提交成功后,向實時消息服務確認發送。只有在得到確認發送指令后,實時消息服務才真正發送該消息;

  3)當用戶A扣款事務提交失敗回滾后,向實時消息服務取消發送。在得到取消發送指令后,該消息將不會被發送;

  4)對於那些未確認的消息或者取消的消息,需要有一個消息狀態確認系統定時去用戶A系統查詢這個消息的狀態並進行更新。為什么需要這一步驟,
舉個例子:假設在第2步用戶A扣款事務被成功提交后,系統掛了,此時消息狀態並未被更新為“確認發送”,從而導致消息不能被發送。

 

 

優點:消息數據獨立存儲,降低業務系統與消息系統間的耦合;

缺點:一次消息發送需要兩次請求;業務處理服務需要實現消息狀態回查接口。


免責聲明!

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



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