1. 程式人生 > >Linq to Sql 事務處理

Linq to Sql 事務處理

Linq to SQL支援三種事務處理模型:顯式本地事務、顯式可分發事務、隱式事務

1. 隱式事務

    當呼叫SubmitChanges 時,L2S會檢查當前環境是否開啟了事務(下面兩節中建立的事務),如果沒有開始事務,則 L2S啟動本地事務(IDbTransaction),並使用此事務執行所生成的 SQL 命令。

    使用Reflector檢視DataContext.SubmitChanges的原始碼(見本文最後的附錄),可以看到,如果開啟了一個事務,並將其傳給DataContext.Transaction,則在執行SubmitChanges時就不會再重新開啟一個新的事務了。

進行此呼叫時,DataContext 會設法將您所做的更改轉換為等效的 SQL 命令。您可以使用自己的自定義邏輯來重寫這些操作,但提交順序是由 DataContext 的一項稱作“更改處理器”的服務來協調的。事件的順序如下:

  1. 當您呼叫 SubmitChanges 時,LINQ to SQL 會檢查已知物件的集合以確定新例項是否已附加到它們。如果已附加,這些新例項將新增到被跟蹤物件的集合。

  2. 所有具有掛起更改的物件將按照它們之間的依賴關係排序成一個物件序列。如果一個物件的更改依賴於其他物件,則這個物件將排在其依賴項之後。

  3. 在即將傳輸任何實際更改時,LINQ to SQL 會啟動一個事務來封裝由各條命令組成的系列。

  4. 對物件的更改會逐個轉換為 SQL 命令,然後傳送到伺服器。

    此時,如果資料庫檢測到任何錯誤,都會造成提交程序停止並引發異常。將回滾對資料庫的所有更改,就像未進行過提交一樣。DataContext 仍具有所有更改的完整記錄。

先執行Insert,再執行Update;執行Update時出現了SqlException異常。這時檢視測試表TLINQ中的資料,發現沒有插入新的記錄進去。也就是說,這裡使用了事務,但是SQL Server Profile沒有跟蹤到
    下面一節中即使執行DbConnection.BeginTransaction(),也不會跟蹤到begin tran和commit tran。

    最後總結一下隱式事務的優缺點:

    優點:使用簡單,L2S都幫我們搞定了,我們不需要寫任何程式碼。

    缺點:只能處理單個DataContext中的單個SubmitChanges()函式的呼叫。如果需要將SubmitChanges()與其他自定義更新操作(譬如ExcuteCommand)共用一個Transaction、或者與其他DataContext共用一個DBTransation

 

2. 顯式本地事務

    SubmitChanges只能處理最基本的CUD(Create/Update/Delete)操作;而在日常的應用中,邏輯往往沒有這麼簡單,或者考慮效能等因素,我們需要配合ADO.Net執行原生的TSQL;這時我們可能要讓ADO.Net + Linq to SQL來進行配合處理。

    也就是說,我們可以手工建立一個DbConnection和DbTransaction,然後傳給DataContext

  優點:可以配合Ado.Net一起使用,或者跨DataContext使用,實現負責的業務邏輯。

    缺點:處理步驟比較繁瑣。L2S中的DataContext已經提供了ExcuteCommand方法來執行原生的TSQL

3. 顯式可分發事務

    使用TransactionScope來進行顯示可分發事務控制。於是這個操作就有了事務功能。關於TransactionScope的詳細介紹,可以參考MSDN:使用事務範圍實現隱式事務,及SQL Server的聯機叢書:CLR 整合和事務

簡潔,把要執行的操作封裝在一個或多個Action中,然後傳遞給TransactioExtension.Excute即可。對於封裝在TransactionScope裡面執行的所有操作(譬如SubmitChanges,ExcuteCommand、ExecuteQuery),最終都會解析為對ADO.NET的呼叫;而ADO.Net會在呼叫 Connection.Open 方法時自動檢查Transaction.Current,並在該事務中以透明方式登記連線(除非在連線字串中將 Enlist 關鍵字設定為 false)。

    SqlConnection 物件的 ConnectionString 屬性支援 Enlist 關鍵字,該關鍵字指示 System.Data.SqlClient 是否檢測事務上下文並在分散式事務中自動登記連線。如果此關鍵字設定為 True(預設設定),則會在開啟的執行緒的當前事務上下文中自動登記連線。如果此關鍵字設定為 False,則 SqlClient 連線不會與分散式事務互動。如果未在連線字串中指定 Enlist,並且如果在開啟相應連線時檢測到一個分散式事務,則會在此分散式事務中自動登記此連線

    優點:使用簡單,可以配合ADO.Net或者DataContext.ExcuteCommand使用,可以跨DataContext使用,可以跨資料庫使用,可以跨伺服器使用。

    缺點:分散式事務通常會使用大量的系統資源。Microsoft 分散式事務處理協調器 (MS DTC) 會管理此類事務,並整合在這些事務中訪問的所有資源管理器。慶幸的是:在開啟一個具有活動TransactionScope事務的連線而未開啟任何其他連線的情況下,該事務會以輕型事務的形式提交,而不是產生完全分散式事務的額外開銷。