TransactionScope如何回滚交易?

时间:2009-01-30 05:19:26

标签: c# .net nhibernate transactions transactionscope

我正在编写集成测试,我将把一些对象插入数据库,然后检查以确定我的方法是否检索这些对象。

我与数据库的连接是通过NHibernate ...而我创建这样一个测试的常用方法是执行以下操作:

NHibernateSession.BeginTransaction();

//use nhibernate to insert objects into database
//retrieve objects via my method
//verify actual objects returned are the same as those inserted

NHibernateSession.RollbackTransaction();

但是,我最近发现了TransactionScope显然可以用于此目的......

有些example code I've found如下:

public static int AddDepartmentWithEmployees(Department dept)
{

    int res = 0;

    DepartmentAdapter deptAdapter = new DepartmentAdapter();
    EmployeeAdapter empAdapter = new EmployeeAdapter();
    using (TransactionScope txScope = new TransactionScope())
    {

        res += deptAdapter.Insert(dept.DepartmentName);
        //Custom method made to return Department ID 
        //after inserting the department "Identity Column"
        dept.DepartmentID = deptAdapter.GetInsertReturnValue();
        foreach(Employee emp in dept.Employees)
        {

            emp.EmployeeDeptID = dept.DepartmentID;
            res += empAdapter.Insert(emp.EmployeeName, emp.EmployeeDeptID);

        }
        txScope.Complete();

    }
    return res;

}

我相信如果我不包含行txScope.Complete(),那么插入的数据将被回滚。但不幸的是,我不明白这是怎么可能的...... txScope对象如何跟踪deptAdapterempAdapter对象及其在数据库上的事务。

我觉得我在这里缺少一些信息......我是否真的能够通过使用BeginTransaction()包围我的代码来替换我的RollbackTransaction(TransactionScope)来电?< / p>

如果没有,那么TransactionScope如何回滚交易?

2 个答案:

答案 0 :(得分:102)

基本上,TransactionScope不会跟踪您的适配器,它的作用是跟踪数据库连接。当您打开数据库连接时,连接将查看是否存在环境事务(事务范围),如果存在,则查看它。注意,如果与同一SQL服务器的连接多一个,则会升级到Distribtued Transaction。

当您使用使用块时会发生什么,即使发生异常,也会确保调用dispose。因此,如果在txScope.Complete()之前调用dispose,则TransactionScope将告诉连接回滚其事务(或DTC)。

答案 1 :(得分:52)

TransactionScope class适用于Transaction class,这是特定于线程的。

创建TransactionScope时,它会检查线程是否有Transaction;如果存在,则使用它,否则,它会创建一个新的并将其推送到堆栈。

如果它使用现有的,那么它只会增加一个计数器以释放(因为你必须在其上调用Dispose)。在最后一个版本中,如果Transaction没有被评估,它将回滚所有工作。

至于为什么类似乎神奇地了解了事务,那么这就是那些希望使用这个模型的类的实现细节。

当您创建deptAdapteremptAdapter个实例时,他们会检查线程上是否有当前事务(Transaction类上的静态Current property) 。如果存在,那么它将自己注册到Transaction,以参与提交/回滚序列(Transaction控制,并可能传播给不同的事务协调器,例如内核,分布式等。 )。