我遇到了使用TransactionScope
时交易无法回滚的问题。
我们将NHibernate与内存中的SQLite数据库一起使用,因此在应用程序的整个生命周期内(在这种情况下,某些单元测试)将我们限制为只有一个数据库连接。
using (var ts = new TransactionScope(TransactionScopeOption.Required,
TimeSpan.Zero))
{
using (var transaction = _repository.BeginTransaction())
{
_repository.Save(entity);
transaction.Commit();
}
// ts.Complete(); <- commented Complete call still commits transaction
}
即使我删除了NHibernate的内部嵌套事务,所以代码如下所示,事务仍然被提交。
using (var ts = new TransactionScope(TransactionScopeOption.Required,
TimeSpan.Zero))
{
_repository.Save(entity);
} // no Complete(), but the transaction still commits
是否期望在TransactionScope
块中新建一个SQLite连接以便在事务中登记?
同样,我无法为其提供新连接,因为这样可以清除数据库。
在撰写本文时,使用NHibernate 3.0和SQLite 1.0.66.0这两个最新版本。
注意:在NHibernate transaction.Rollback()
对象上使用ITransaction
正确回滚事务,这只是TransactionScope
支持似乎不起作用。
答案 0 :(得分:1)
我想我可能已经找到了原因。如果未从TransactionScope块内部打开连接,则不会在事务中登记该连接。
这里有一些信息: http://msdn.microsoft.com/en-us/library/aa720033(v=vs.71).aspx
解决方案:
我的存储库中已经有了.BeginTransaction()
方法,所以我想我会在那里的环境事务中手动登记连接。
这是我最终得到的代码:
/// <summary>
/// Begins an explicit transaction.
/// </summary>
/// <returns></returns>
public ITransaction BeginTransaction()
{
if (System.Transactions.Transaction.Current != null)
{
((DbConnection) Session.Connection).EnlistTransaction(System.Transactions.Transaction.Current);
}
return Session.BeginTransaction();
}
以下是我使用它的方式:
using (var ts = new TransactionScope(TransactionScopeOption.Required, TimeSpan.Zero))
using (var transaction = repository.BeginTransaction())
{
repository.Save(entity);
transaction.Commit(); // nhibernate transaction is commited
// ts.Complete(); // TransactionScope is not commited
} // transaction is correctly rolled back now