TransactionScope如何回滚事务?

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

我的数据库的连接是通过NHibernate的……我创build这样一个testing通常的方法是做到以下几点:

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 。

我find的一些示例代码如下所示:

 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对象及其事务。

我觉得我错过了一些信息在这里…我真的能够通过使用TransactionScope围绕我的代码来代替我的BeginTransaction()RollbackTransaction( )调用吗?

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

本质上TransactionScope不跟踪你的适配器,它跟踪数据库连接。 当你打开一个数据库连接时,连接将会查看是否有一个环境事务(Transaction Scope),如果有的话就使用它。 小心如果有更多的连接到同一个SQL服务器,这将升级到分布式事务。

发生了什么事情,因为你正在使用一个使用块,你确保处置将被称为即使发生exception。 所以如果在txScope.Complete()之前调用dispose,TransactionScope会告诉连接回滚他们的事务(或DTC)。

TransactionScope类适用于线程特定的Transaction类 。

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

如果它使用现有的,那么它只是增加一个发布计数器(因为你必须调用Dispose )。 在最后一个版本中,如果Transaction没有完成,它会回滚所有的工作。

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

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