以可序列化隔离级别开始事务是否会立即阻塞?
Does beginning a transaction with a serializable isolation level block immediately?
如果另一个线程对 Table1
进行的任何读取 (SELECT
),在事务开始之后但在执行 UPDATE
之前被阻塞,或者 UPDATE
需要先开始执行吗?
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();
_cmd.Transaction.Commit();
在 SQLite 中,所有事务(显式和自动事务)都是可序列化的。
默认情况下,SQLite 的事务 are DEFERRED,这意味着 read/write 锁仅在数据库文件实际需要 read/written 时才使用(并且写入通常仅在缓存在事务提交时刷新)。
在journal rollback模式下,readers和writer互相阻塞; WAL模式下,readers和writer可以并发访问DB,但仍然只能有一个writer。
但是,Xamarin 不使用默认值; BeginTransaction() 立即以 EXCLUSIVE 模式启动事务,这意味着它与所有其他并发事务冲突。 (WAL 模式没有区别。)
显然,您不应该在 Xamarin 中使用任何并发。
如果另一个线程对 Table1
进行的任何读取 (SELECT
),在事务开始之后但在执行 UPDATE
之前被阻塞,或者 UPDATE
需要先开始执行吗?
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();
_cmd.Transaction.Commit();
在 SQLite 中,所有事务(显式和自动事务)都是可序列化的。
默认情况下,SQLite 的事务 are DEFERRED,这意味着 read/write 锁仅在数据库文件实际需要 read/written 时才使用(并且写入通常仅在缓存在事务提交时刷新)。
在journal rollback模式下,readers和writer互相阻塞; WAL模式下,readers和writer可以并发访问DB,但仍然只能有一个writer。
但是,Xamarin 不使用默认值; BeginTransaction() 立即以 EXCLUSIVE 模式启动事务,这意味着它与所有其他并发事务冲突。 (WAL 模式没有区别。) 显然,您不应该在 Xamarin 中使用任何并发。