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
对象如何跟踪数据库上的deptAdapter
和empAdapter
对象及其事务。
我觉得我错过了一些信息在这里…我真的能够通过使用TransactionScope
围绕我的代码来代替我的BeginTransaction()
和RollbackTransaction(
)调用吗?
如果不是,那么TransactionScope
如何回滚事务?
本质上TransactionScope不跟踪你的适配器,它跟踪数据库连接。 当你打开一个数据库连接时,连接将会查看是否有一个环境事务(Transaction Scope),如果有的话就使用它。 小心如果有更多的连接到同一个SQL服务器,这将升级到分布式事务。
发生了什么事情,因为你正在使用一个使用块,你确保处置将被称为即使发生exception。 所以如果在txScope.Complete()之前调用dispose,TransactionScope会告诉连接回滚他们的事务(或DTC)。
TransactionScope
类适用于线程特定的Transaction
类 。
在创buildTransactionScope
,它会检查线程是否有Transaction
; 如果存在,则使用它,否则,它创build一个新的并将其推入堆栈。
如果它使用现有的,那么它只是增加一个发布计数器(因为你必须调用Dispose
)。 在最后一个版本中,如果Transaction
没有完成,它会回滚所有的工作。
至于为什么类似乎神奇地知道事务,那么这些就是那些希望使用这个模型的类的实现细节。
在创builddeptAdapter
和emptAdapter
实例时,它们将检查线程上是否有当前事务( Transaction
类上的静态Current
属性 )。 如果存在,那么它会注册自己的Transaction
,参与提交/回滚序列(哪些Transaction
控制,并可能传播到不同的事务协调器,如内核,分布式等)。