106

我正在编写一个集成测试,我将在其中将许多对象插入数据库,然后检查以确保我的方法是否检索到这些对象。

我与数据库的连接是通过 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显然可以用于这个目的......

我发现的一些示例代码如下:

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()and ) 调用吗?RollbackTransaction(TransactionScope

如果不是,那么如何TransactionScope回滚事务?

4

2 回答 2

115

本质上,TransactionScope 不会跟踪您的适配器,它所做的是跟踪数据库连接。当您打开数据库连接时,连接将查看是否存在环境事务(事务范围),如果有,则加入该事务。注意,如果有多个连接到同一个 SQL 服务器,这将升级为分布式事务。

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

于 2009-01-30T05:49:11.797 回答
57

该类与特定于线程 TransactionScope类一起使用。Transaction

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

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

至于为什么类似乎神奇地知道事务,这留给那些希望使用这个模型的类作为实现细节。

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

于 2009-01-30T05:50:03.043 回答