TransactionScope 与 SQLite 内存数据库和 NHibernate
Posted
技术标签:
【中文标题】TransactionScope 与 SQLite 内存数据库和 NHibernate【英文标题】:TransactionScope with SQLite in-memory database and NHibernate 【发布时间】:2011-03-20 15:37:32 【问题描述】:我遇到了使用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 ITransaction
对象上使用 transaction.Rollback()
可以正确回滚事务,只是 TransactionScope
支持似乎不起作用。
【问题讨论】:
SQLite(及其驱动程序)是否支持分布式事务,还是明确知道 TransactionScope? @diego:是的,根据 SQLite ADO.NET 提供者论坛上的帖子,TransactionScope 已经支持几年了。 “自动分布式事务登记”也是他们主页上注明的功能之一。 如果在范围结束后检查,数据是否持久化? 【参考方案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
【讨论】:
以上是关于TransactionScope 与 SQLite 内存数据库和 NHibernate的主要内容,如果未能解决你的问题,请参考以下文章
内存中的 Sqlite - TransactionScope - 已检测到环境事务
将 TransactionScope 与实体框架 6 一起使用