淺析SQL Server實現分布式事務的兩階段提交協議2PC


不久之前團隊有個新人問我一個很重要的web服務接口如何保證事務的問題。因為涉及到跨庫事務,當時我只是回答目前我們的SOA框架都不支持跨庫事務。然后就問到了數據庫跨庫事務是如何實現的,我只能憑印象含糊回答多數是基於數據庫日志(后來知道就是所謂的預寫日志Write-Ahead Logging),具體數據庫內部如何控制數據一致性則真的說不清楚。后來一起查了一下事務的資料,原來DB的事務控制除了基於預寫日志還要實現兩階段提交協議(2PC),參考MSDN摘抄兩段加深印象。

一、2PC的兩個階段

1、准備階段(Prepare Phase)

When the transaction manager receives a commit request, it sends a prepare command to all of the resource managers involved in the transaction. Each resource manager then does everything required to make the transaction durable, and all buffers holding log images for the transaction are flushed to disk. As each resource manager completes the prepare phase, it returns success or failure of the prepare to the transaction manager.

2、提交階段(Commit Phase)

If the transaction manager receives successful prepares from all of the resource managers, it sends commit commands to each resource manager. The resource managers can then complete the commit. If all of the resource managers report a successful commit, the transaction manager then sends a success notification to the application. If any resource manager reported a failure to prepare, the transaction manager sends a rollback command to each resource manager and indicates the failure of the commit to the application.

 

二、2PC的原理示例

如何理解2PC實現分布式事務的呢?下面舉例說明下。

假設有A、B、C三個數據庫,A作為一個事務發起者,稱為“主庫”,B和C則稱為”從庫”。假設需要執行一個在A、B和C三個庫的某個表中插入一行數據的事務。

准備階段(Prepare Phase),A鎖定表,並將事務寫入自己的預寫日志;A將事務發給從庫B和C,B和C也各自鎖定自己的表,並把事務寫入預寫日志,完成后返回告訴A准備階段完成;
提交階段(Commit Phase),A開始執行自己的事務,並通知B和C提交事務。如果在這個過程中沒有任何錯誤,那么操作將在A、B和C庫中完成;如果發生錯誤,比如從庫C超時無響應,或者從庫C磁盤空間不足…A將通知所有參與事務的B和C回滾該事務,並且回滾A自己的事務。

dbtrans

 

順便重點再提一下預寫日志,因為數據庫的這種日志無比重要,普通的增刪改查、數據還原、單庫事務以及本文的分布式事務都離不開它,沒有它絕大多數主流數據庫的數據一致性根本無法實現。

到這里大家應該已經看到,相比單庫事務,分布式事務控制更加復雜,而且開銷極大。雖然一些高級開發框架如.net framework提供了較為強大豐富的類庫如TransactionScope來簡化開發分布式事務,但是建議能不用則不用,因為它被反映普遍存在性能問題無意識的死鎖問題。這種分布式事務的場景如果頻繁出現,重新拆分系統合理規划架構才是正道。

 

總結:在大型web應用中如何保持事務這個話題被問得非常多,個人已經是不止一次被問到所維護的站點是如何實現事務的。在分布式多集群環境下,業務邏輯錯綜復雜,保證數據庫完全可靠存儲當然並不容易。但是web應用程序的一個典型特點是讀多寫少,犧牲極少的數據一致性獲得系統的高可擴展性可維護性以及高性能,那么一點點的數據不准確在業務上完全可以容忍,何況我們有日志,后續還有很多補償措施,甚至直接人工介入處理也未嘗不可。

 

參考:

http://msdn.microsoft.com/en-us/library/ms191440.aspx

http://technet.microsoft.com/zh-cn/library/ms186259(v=SQL.105).aspx

http://www.cnblogs.com/CareySon/archive/2012/02/13/2349751.html

http://www.cnblogs.com/CareySon/archive/2012/02/14/2351149.html


免責聲明!

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



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