Serializable隔离级别事务启动是否立即阻塞?UPDATE执行前读操作是否被阻塞?
SQLite Serializable事务与阻塞问题解答
咱们逐个拆解你的问题,结合给出的代码示例来分析:
问题1:以Serializable隔离级别启动事务是否会立即造成阻塞?
答案是不会。执行_con.BeginTransaction(IsolationLevel.Serializable);只是在当前连接上创建一个事务上下文,这时候并没有对数据库的任何资源(表、行)加锁,所以不会立刻阻塞其他线程的操作。
问题2:事务启动但UPDATE执行前,其他线程的SELECT是否会被阻塞?
同样不会被阻塞。阻塞的触发是从实际执行写操作(这里就是UPDATE语句)开始的:当_cmd.ExecuteReader();执行时,SQLite会为Table1中Id=1的行(或根据锁定模式,可能是整个表)获取排他锁,这时候如果其他线程尝试对该行(或表)进行写操作,或者在Serializable级别下的特定读操作才会被阻塞。而在UPDATE执行前,你的事务还没有持有任何锁,其他线程的SELECT可以正常读取数据。
结合代码梳理流程:
var _con = new SqliteConnection( "Data Source=" + FileName ); _con.Open(); SqliteCommand _cmd = _con.CreateCommand(); _cmd.CommandType = CommandType.Text; _con.BeginTransaction(IsolationLevel.Serializable); // 仅启动事务,无锁,不阻塞 // UPDATE _cmd.CommandText = "UPDATE Table1 SET field1 = 'a' WHERE Id = 1"; _cmd.ExecuteReader(); // 执行UPDATE时才加锁,此时才可能触发阻塞其他操作 _cmd.Transaction.Commit();
补充说明:SQLite的Serializable隔离级别默认采用延迟加锁机制(BEGIN DEFERRED),只有当事务执行第一个读写操作时,才会尝试获取对应的锁,这也进一步验证了前面的结论。
内容的提问来源于stack exchange,提问作者samus
相关产品推荐
相关产品推荐

