Nhibernate 带有TransactionScope和增量标识生成器的SQLite
当尝试将SQLite与System.Transactions一起使用时,我注意到当NHibernate尝试检索下一个标识号时,我遇到了一个异常(下面给出了代码) 这似乎是因为新的SQLite连接正在自动登记当前事务。据我所知,SQLite只支持单个写事务,但应该支持多个读事务,所以我很惊讶我得到了一个数据库锁定的读操作异常。是否有人以这种方式将SQLite与事务作用域一起使用 如果使用NHibernate事务而不是TransactionScope,同样的代码也可以正常工作 代码块:Nhibernate 带有TransactionScope和增量标识生成器的SQLite,nhibernate,sqlite,transactionscope,Nhibernate,Sqlite,Transactionscope,当尝试将SQLite与System.Transactions一起使用时,我注意到当NHibernate尝试检索下一个标识号时,我遇到了一个异常(下面给出了代码) 这似乎是因为新的SQLite连接正在自动登记当前事务。据我所知,SQLite只支持单个写事务,但应该支持多个读事务,所以我很惊讶我得到了一个数据库锁定的读操作异常。是否有人以这种方式将SQLite与事务作用域一起使用 如果使用NHibernate事务而不是TransactionScope,同样的代码也可以正常工作 代码块:
using (var scope = new TransactionScope())
{
var userRepository =
container.GetInstance<IUserRepository>();
var user = new User();
userRepository.SaveOrUpdate(user);
scope.Complete();
}
这里有两件事在起作用 正如您所提到的,
System.Data.SQLite
将自动登记到分布式事务中。默认情况下,此选项处于启用状态,可以通过添加inclist=no
将其禁用
第二个是默认情况下,System.Data.SQLite
使用自动写锁创建事务。这是基于这样的假设来完成的,即如果事务启动,将完成写操作。这可以通过使用Serializable.ReadCommitted
启动事务来覆盖
也可以使用DefaultIsolationLevel
键在连接字符串中指定默认值。有效值仅为ReadCommitted
和Serializable
。SQLite不支持其他隔离级别ReadCommitted
延迟写锁,而Serializable
立即获得写锁
Unspecified将使用连接字符串中指定的默认隔离级别。如果连接字符串中未指定隔离级别,则使用Serializable。可序列化事务是默认设置。在这种模式下,引擎会立即锁定数据库,其他线程不能开始事务。其他线程可以从数据库中读取,但不能写入
使用ReadCommitted隔离级别,锁会根据需要延迟和提升。多个线程可以在ReadCommitted模式下启动事务,但如果一个线程尝试提交一个事务,而另一个线程具有ReadCommitted锁,则可能会超时或导致两个线程上的死锁,直到达到两个线程的CommandTimeout
我确实查看了“登记”选项,但我无法关闭该选项,因为我需要显式登记它,并且我将无法访问该选项的连接对象。能否指定ConnectionString中用于指定默认事务隔离级别的键。MSDN文档说明TranactionScope的默认隔离级别为ReadCommitted@DineshManne,我编辑了答案,添加了更多关于默认隔离级别的信息。我不确定您具体指的是哪些关于MSDN和TransactionScope的文档,但SQLite不支持不同类型的事务隔离级别,就像其他数据库一样,它为稍微不同的目的重用隔离级别(用于其他数据库不必具备的目的)。SQLite以前没有这样做,它过去在SQLiteConnection上只有一个自定义重载,但是如果不直接引用SQLiteConnection类,就不可能使用延迟锁。当一个线程尝试启动一个事务而另一个事务处于活动状态时,我遇到了获取“Database file is locked”异常的问题。最好是将任何事务放在锁{}内,还是这可能会导致其他问题?
19:34:19,126 ERROR [ 7] IncrementGenerator [(null)]- could not get
increment value
System.Data.SQLite.SQLiteException: The database file is locked
database is locked
at System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)
at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()
at System.Data.SQLite.SQLiteTransaction..ctor(SQLiteConnection
connection, Boolean deferredLock)
at System.Data.SQLite.SQLiteConnection.BeginTransaction(Boolean
deferredLock)
at System.Data.SQLite.SQLiteConnection.BeginTransaction()
at System.Data.SQLite.SQLiteEnlistment..ctor(SQLiteConnection cnn,
Transaction scope)
at
System.Data.SQLite.SQLiteConnection.EnlistTransaction(Transaction
transaction)
at System.Data.SQLite.SQLiteConnection.Open()
at NHibernate.Connection.DriverConnectionProvider.GetConnection()
at NHibernate.Id.IncrementGenerator.GetNext(ISessionImplementor
session)
19:34:20,063 ERROR [ 7] ADOExceptionReporter [(null)]- The database
file is locked
database is locked