Nhibernate 带有TransactionScope和增量标识生成器的SQLite

Nhibernate 带有TransactionScope和增量标识生成器的SQLite,nhibernate,sqlite,transactionscope,Nhibernate,Sqlite,Transactionscope,当尝试将SQLite与System.Transactions一起使用时,我注意到当NHibernate尝试检索下一个标识号时,我遇到了一个异常(下面给出了代码) 这似乎是因为新的SQLite连接正在自动登记当前事务。据我所知,SQLite只支持单个写事务,但应该支持多个读事务,所以我很惊讶我得到了一个数据库锁定的读操作异常。是否有人以这种方式将SQLite与事务作用域一起使用 如果使用NHibernate事务而不是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