【转】C#中使用TransactionScope类(分布式事务) 和 锁
如果在C#中使用TransactionScope類(分布式事務),則須注意如下事項:
1、在項目中引用using System.Transactions命名空間(先要在添加net組件的引用);
2、具體示例如下:
?
public static void sendMessage(){ TransactionOptions transactionOption = new TransactionOptions();//設置事務隔離級別transactionOption.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;// 設置事務超時時間為60秒transactionOption.Timeout = new TimeSpan(0, 0, 60);using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOption)){try{//TODOscope.Complete();}catch (Exception ex) {throw new Exception(ex.Message);}finally{//釋放資源scope.Dispose();} }}?
namespace System.Transactions {//// Summary:// Specifies the isolation level of a transaction.public enum IsolationLevel{//// Summary:// Volatile data can be read but not modified, and no new data can be added during the transaction.可讀取但不可修改易失性數據,并且在此過程中不能添加新數據交易。Serializable = 0,//// Summary:// Volatile data can be read but not modified during the transaction. New data can be added during the transaction.在事務期間可以讀取但不能修改易失性數據。新數據可以在事務處理期間添加。RepeatableRead = 1,//// Summary:// Volatile data cannot be read during the transaction, but can be modified.事務期間無法讀取易失性數據,但可以對其進行修改。ReadCommitted = 2,//// Summary:// Volatile data can be read and modified during the transaction.在事務期間可以讀取和修改易失性數據。ReadUncommitted = 3,//// Summary:// Volatile data can be read. Before a transaction modifies data, it verifies if// another transaction has changed the data after it was initially read. If the// data has been updated, an error is raised. This allows a transaction to get to// the previously committed value of the data.可以讀取易失性數據。在事務修改數據之前,它會驗證另一個事務在最初讀取數據后更改了數據。如果數據已更新,出現錯誤。這使得事務可以到達以前提交的數據值。Snapshot = 4,//// Summary:// The pending changes from more highly isolated transactions cannot be overwritten.無法覆蓋來自高度隔離事務的掛起更改。Chaos = 5,//// Summary:// A different isolation level than the one specified is being used, but the level cannot be determined. An exception is thrown if this value is set.正在使用與指定隔離級別不同的隔離級別,但無法確定。如果設置了此值,則會引發異常。Unspecified = 6} }?
?
事務五種隔離級別IsolationLevel屬性一共支持五種事務設置,具體介紹如下:
(1)DEFAULT
使用數據庫設置的隔離級別(默認),由DBA 默認的設置來決定隔離級別。
(2)READ_UNCOMMITTED
這是事務最低的隔離級別,它充許別外一個事務可以看到這個事務未提交的數據。
會出現臟讀、不可重復讀、幻讀 (隔離級別最低,并發性能高)。
(3)READ_COMMITTED
保證一個事務修改的數據提交后才能被另外一個事務讀取。另外一個事務不能讀取該事務未提交的數據。
可以避免臟讀,但會出現不可重復讀、幻讀問題(鎖定正在讀取的行)。
(4)REPEATABLE_READ
可以防止臟讀、不可重復讀,但會出幻讀(鎖定所讀取的所有行)。
(5)SERIALIZABLE
這是花費最高代價但是最可靠的事務隔離級別,事務被處理為順序執行。
保證所有的情況不會發生(鎖表)。
?
3、對MSDTC組件設置:
???? 在控制面板--->管理工具--->服務 中,開啟Distributed Transaction Coordinator 服務。
???? a.控制面板->管理工具->組件服務->計算機->我的電腦->右鍵->屬性
??? ?b.選擇MSDTC頁, 確認"使用本地協調器"
???? c.點擊下方"安全配置"按鈕
???? d.勾選: "允許網絡DTC訪問","允許遠程客戶端","允許入站","允許出站","不要求進行身份驗證".
???? e.對于數據庫服務器端, 可選擇"要求對呼叫方驗證"
???? f.勾選:"啟用事務Internet協議(TIP)事務"。
???? g.在雙方防火墻中增加MSDTC.exe例外
???? 可用命令行: netsh firewall set allowedprogram %windir%\system32\msdtc.exe MSDTC enable
4、重啟IIS服務器。
?
?
2 鎖
鎖有樂觀鎖和悲觀鎖
2.1樂觀鎖實現方法有兩種
2.1.1加入時間戳
2.1.2 在UPDATE數據前對數據進行比對
Set @money=Select money from account where accountId=1Update account set money =2000 where accountId=1 and money=@money這就實現了一個最簡單的樂觀鎖,在update之前對拿到的數據進行判斷或者加入時間搓機制
2.2 悲觀鎖
在事務一開始就對你后面要修改的記錄鎖定
Select * from account with (UPDLOCK) where accountId=1一但鎖住,accountId=1 這一個記錄 在此事務結束前,別人都無法對其進行修改或讀取,要等待此事務結束。
使用悲觀鎖,千萬不要用以下語句
Select top 1 * from account with (UPDLOCK)這樣會鎖住account整個表,其他事務都無法對此表進行讀取或者修改
在并發量不大的時候可以使用悲觀鎖,一但我要修改某條記錄,我就鎖住它,直到我整個事務完成。
并發量比較大的還是要使用樂觀鎖,但是要有失敗處理機制。
?
參考
TransactionScop事務機制的使用
臟讀、不可重復讀 共享鎖、悲觀鎖 和 事務五種隔離級別
?
總結
以上是生活随笔為你收集整理的【转】C#中使用TransactionScope类(分布式事务) 和 锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 首发加入XGP!《盟军敢死队3高清复刻版
- 下一篇: c# char unsigned_dll