Transaction in ADO.net 2.0
Posted on 2005-08-15 20:28 idior 閱讀(3907) 評論(12) 編輯 收藏 引用 網摘 所屬分類: Windbey 在談具體實現前 先介紹一下三種事務:
1. 單對象單資源
2. 多對象單資源
3. 多對象多資源(分佈式事務, 使用兩段提交協議)
在ADO.Net1.0下有兩種使用Transaction的方法. 一種是在需要事務的對象中顯式的調用事務處理, 還有一種是使用Enterprise Service的聲明式的方法.
第一種方法的示例代碼如下:
{
string connectionString = "";
IDbConnection connection = new SqlConnection(connectionString);
connection.Open();
IDbCommand command = new SqlCommand();
command.Connection = connection;
IDbTransaction transaction;
transaction = connection.BeginTransaction(); //Enlisting database
command.Transaction = transaction;
try
{
/* Interact with database here, then commit the transaction
*/
transaction.Commit();
}
catch
{
transaction.Rollback(); //Abort transaction
}
finally
{
connection.Close();
}
}
這種方法使用起來相當麻煩, 而且只能針對一個對象訪問一個資源的事務. 如果事務涉及多個對象,那麼由誰來進行事務處理? 如果事務使用了多個資源, 那樣又涉及到分佈式事務和兩段提交協議,此時依靠第一種方法完全由用戶自己控制實在過於複雜,因此在提供了第一種基本方法後, ADO.Net 1.0又利用Com+實現了聲明式的事務處理,示例代碼如下:
[Transaction]
public class MyComponent : ServicedComponent
{
[AutoComplete]
public void MyMethod()
{
/*Interact with other serviced components
and resource managers */
}
}
這種聲明式的方法看上去似乎很好,但是也隱含了許多問題.
1. 使用事務的對象需要繼承ServicedComponent
2. 即使不涉及多資源的分佈式事務而僅僅是涉及到了多個對象的簡單事務(開頭介紹的第二種事務),我也要使用此方法,影響了效率. 這樣的弊端和J2ee中的都在本地的Entity Bean之間進行通訊很像,殺雞也不得不用牛刀.
3. 不可避免的使用了Com+.
4. 使用Enterprise Services的事務總是線程安全的, 也就是說你無法讓多個線程參與到同一個事務中.
ADO.Net2.0 提供的新的事務模型綜合了前兩者的優點,
1 在簡單(不涉及分佈式)事務中也可以使用聲明式的事務處理方法, 而不必使用Com+容器, ADO.net 2.0中提供了一個輕量級的事務容器.
2 用戶根本不需要考慮是簡單事務還是分佈式事務. 新模型會自動根據事務中涉及的對象資源判斷使用何種事務管理器. 簡而言之, 對於任何的事務用戶只要使用同一種方法進行處理. 示例代碼:
{
/* Perform transactional work here */
//No errors - commit transaction
scope.Complete();
}
另外對嵌套事務和事務的隔離級別也提供了支持, 在此就不作詳細介紹. Fantasy Soft對此做了介紹.
//Default is Required
{
using(TransactionScope scope2 = new
TransactionScope(TransactionScopeOption.Required))
{}
using(TransactionScope scope3 = new
TransactionScope(TransactionScopeOption.RequiresNew))
{}
using(TransactionScope scope4 = new
TransactionScope(TransactionScopeOption.Suppress))
{}
}
options.IsolationLevel = IsolationLevel.ReadCommitted;
options.Timeout = TransactionManager.DefaultTimeout;
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options))
{
ReadUncommitted,
ReadCommitted,
RepeatableRead,
Serializable,
Unspecified,
Chaos, //No isolation whatsoever
Snapshot //Special form of read committed 8
supported by SQL Server 2005
}
本文僅僅是ADO.net 2.0 Transaction的簡單介紹, 詳細資料查看M$的相關文檔.
參考資料: Introducing System.Transactions by Juval Lowy