天天看點

c#傳統SqlTransaction事務和TransactionScope事務

事務有很多種,看了一些關于事務的問題,這裡做下筆記·····

事務時單個的工作機關。如果某一事務成功,則在該事務中進行的所有資料更改均會送出,成為資料庫中永久的組成部分。若果事務遇到錯誤,則必須取消或復原,所有資料均被更改清除。

屬性:

1.原子性:事務是一個完整的操作,事務的各元素師不可分的。

2.一緻性:事務開始時和完成時,資料必須處于一緻的狀态。

3.隔離性:對資料進行修改的所有并發事務是彼此隔離的。

4.持久性:事務完成後,它對系統的影響是永久的。

1.連接配接相關SqlTransaction事務

Transact-SQL使用下列語句來管理事務:

開始事務:BEGIN TRANSACTION

送出事務:COMMIT TRANSACTION

復原:ROLLBACK TRANSACTION

private static void ExecuteSqlTransaction(string connstr)
        {
            using (SqlConnection conn = new SqlConnection(connstr))
            {
                conn.Open();               
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    SqlTransaction transaction = conn.BeginTransaction("SampleTransaction"); //開始事務
                    cmd.Connection = conn;
                    cmd.Transaction = transaction;
                    try
                    {
                        cmd.CommandText =
                            "Insert into Department (ID, Name) VALUES (2, \'開發部\')";
                        cmd.ExecuteNonQuery();
                        cmd.CommandText =
                            "Insert into Users(ID, Name,DepartmentID) VALUES (2, \'sxw\',2)";
                        cmd.ExecuteNonQuery();
                        transaction.Commit(); //事務完成之後送出事務
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback(); //如果事務沒有完成,就復原事務
                    }
                }                               
            }
        }      

注意:在送出或復原 SqlTransaction 時,應始終使用 Try/Catch 進行異常處理。如果連接配接終止或事務已在伺服器上復原,則Commit 和Rollback 都會生成InvalidOperationException

雖然SqlTransaction事務應用很廣泛,但SqlTransaction事務也有自己的缺點,就是不能實作分布式事務、嵌套事務、編寫也麻煩。下面介紹能實作分布式事務的方法,程式設計相對來說還是很友善的

2.TransactionScope實作分布式事務

想在程式設計中使用TransactionScope實作分布式事務,

首先要在電腦服務中啟動MSDTC(Distributed Transaction Coordinator)服務····

(注意:MSDTC服務隻要把資料互動的電腦上的此服務打開就可以,如果是用戶端直接通路伺服器,則用戶端和伺服器的MSDTC服務都要打開,

如果用戶端隻是與中間層互動,中間層才與伺服器資料互動,則用戶端的MSDTC服務可以不用打開,但中間層和伺服器的MSDTC服務必須啟動。

在第一次啟動MSDTC服務時,服務的啟動類型都是手動啟動,這是可以把啟動類型改成自動啟動,這樣下次就不需要自己手動啟動了)

其次需要在項目中添加對System.Transactions的引用

最後就可以在代碼中引用TransactionScope的Complete方法。進行事務操作。

//使用事務保證原子性
            using (TransactionScope ts = new TransactionScope())
            {
                SqlHelp.ExecuteNonQuery("Insert into Department (ID, Name) VALUES (@Id, \'開發部\')",
                new SqlParameter("@Id", Id));
                SqlHelp.ExecuteNonQuery("Insert into Users(ID, Name,DepartmentID) VALUES (@Id, \'sxw\',2)",
                    new SqlParameter("@Id", Id));
                ts.Complete(); //完成事務,這個必須加上,要不然事務不會有效
            }      

TransactionScope也可以實作嵌套式事務,也就是A調用B,B中聲明了TransactionScope事務,A中也聲明了,這樣如果B沒錯,但是A調完B後出錯,則B中的資料庫操作也復原。