转自:享受代码,享受人生
http://www.cnblogs.com/idior/archive/2005/08/15/214300.html
在谈具体实现前 先介绍一下三种事务:
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