在 sqlite3
控制台中:
sqlite>
CREATE TABLE items (id PRIMARY KEY);
BEGIN;
SELECT * FROM items;
INSERT INTO items VALUES(78);
sqlite> _
然后在第二个控制台中:
sqlite>
.timeout 10000;
BEGIN;
SELECT * FROM items;
INSERT INTO items VALUES(78);
Error: database is locked
sqlite> _
“数据库已锁定”- 错误立即发生,这不可能是对的,对吧?
如果我在第二个控制台中省略了 SELECT,繁忙的处理程序将在 INSERT 处等待 10 秒。我发现使用 BEGIN EXCLUSIVE
也会使第二个事务等待 10 秒,但随后在 BEGIN 语句处。 (我已经解决了这个问题。)
我的问题:这是一个错误,还是应该如此?如果这是预期的行为,那么为什么?
谢谢!
(SQLite v3.7.6)
最佳答案
第二个事务在第一个事务释放其写锁之前无法完成,而第一个事务在第二个事务释放其读锁之前无法完成。因此,立即回滚第二个是有意义的,因为它无法在任何时间内完成,所以第一个可以完成,您可以重试。
BEGIN EXCLUSIVE
立即获取独占锁,而不是等待第一个查询,这解释了您看到的差异。
您应该在事务中注意锁定的数据库(SQLITE_BUSY
),如果发生这种情况,请回滚并重试。超时繁忙处理程序不会保护这些。
关于database - 并发 BEGIN–SELECT–INSERT 导致即时 SQLite3.7.6 "database locked"-error,覆盖忙超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6002333/