在實際開發工作中,執行一個事件,然後調用另一接口插入數據,如果處理邏輯出現異常,那麼之前插入的數據將成為垃圾數據,
我們所希望的是能夠在整個這個方法定義為一個事務,TransactionScope 類提供一個簡單方法,通過這一方法,您不必與事務本身交互,
即可將代碼塊標記為參與某個事務。TransactionScope對象創建了一個事務,同時將該事務設置給Transaction類的Current屬性。
一、TransactionScope的優點
1、使用起來比較方便.TransactionScope可以實現隱式的事務,使你可以在寫數據訪問層代碼的時候不用考慮到事務,而在業務層的控制事務.
2、可以實現分佈式事務,比如跨庫或MSMQ。
二、TransactionScope缺點
1、性價比不高.比如,你只是在"Scope"裡控制一個庫的事務.用"TransactionScope"就有點浪費了.
2、一般情況下只要你使用"TransactionScope",都要配置MSDTC,要配防火牆,要開139端口.這個端口不可以更改
3、在Net Core後 TransactionScope已經沒有用了,用Net core的請尋找其他解決辦法。
三、如果你不得不用分佈式事務,那也得琢磨琢磨
1.這步操作一定得在事務當中嗎?這步操作如果沒完成或者失敗了,值得回滾整個事務嗎?難道沒有優雅的補償措施或者容錯措施?
2.分佈式事務涉及到的點,必須的這麼多?必須得實時的操作這一大串?不能通過通知類操作去精簡掉某些點?
3.在發起分佈式事務之後,你是不是做了事務無關的操作,儘管這些操作跟事務無關?(如,讀取數據、計算、等用戶返回消息、等其他模塊的調用返回等等)要知道事務應該儘快結束。
4.你沒有把一些讀操作也算在事務裡面了吧?這是很容易犯的錯誤,你在事務中Enlist了一個select 操作。
5.你的操作,某些步驟可以等全部操作完成之後再執行.這類操作具有明顯的通知類特點。通知類操作是說,我給你一個通知,並且我保證通知到了你;
你必須吃下這個通知,並且保證處理成功,但是你不必我一通知你你就處理。這樣的操作很明顯可以用另外一個任務去搞。
四、使用分佈式事務注意如下幾點
1:確保參與事務的machine開啟了分佈式事務支持;
2:如果machine開啟了防火牆,需要設置msdtc進程為例外;
3:參與事務的machine不能跨域(如果跨域,目前微軟還沒有確切的解決方案);
4:多數據庫時才使用分佈式事務,如果是同一個數據庫,最好使用SqlTransaction.
四,下面說一下配置流程
1、先添加System.Transactions的引用(需要添加Net程序集)
C#調用時的代碼如下:
<code>using System.Transactions;using (TransactionScope scope = new TransactionScope()){ //trancation one do something... string sql1 = "UPDATE dbo.TestUser SET name='ccc' WHERE id = 2"; ExecuteNonQuery(sql1); //trancation two do something... string sq2 = "UPDATE dbo.TestUser SET name='ccc' WHERE id = 2"; ExecuteNonQuery(sql2); //submit scope.Complete();}/<code>
2、設置web服務器及sql服務器環境配置
<code>控制面板->系統和安全->管理工具->組件服務(WEB服務器和SQL服務器都需要配置此項)/<code>
<code>控制面板->系統和安全->管理工具->服務(WEB服務器和SQL服務器都需要配置此項)/<code>
<code>控制面板->系統和安全->Windows防火牆(WEB服務器和SQL服務器都需要配置此項)/<code>
3、MSSQL配置
<code>對服務器連接,右鍵->屬性/<code>
4、配置Hosts(只配置WEB服務器即可,如果不行,在SQL服務器上也配置上)
<code>C:\\Windows\\System32\\drivers\\etchosts文件,用記事本打開(在WEB服務器上的Hosts文件中需要配置SQL服務器的信息)(如果測試通不過,在SQL服務器上的Hosts文件中配置上WEB服務器的信息)/<code>
分類: C#/Web, SQL Server
閱讀更多 鵝是程序猿 的文章