并发BEGIN-SELECT-INSERT导致SQLite3.7.6即时“数据库锁定” - 错误,覆盖忙超时?

时间:2011-05-14 14:08:20

标签: database concurrency transactions sqlite

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)

2 个答案:

答案 0 :(得分:2)

第二个事务在第一个事务释放其写锁定之前无法完成,第一个事务无法完成,直到第二个事务释放其读锁定。因此有意义的是立即回滚第二个,因为它无法在任何时间内完成,所以第一个可以完成,你可以再试一次。

BEGIN EXCLUSIVE立即获取排他锁,而不是等待第一个查询,这解释了您看到的差异。

在事务中,您应该注意锁定的数据库(SQLITE_BUSY),如果发生这种情况,请回滚并再试一次。超时忙处理程序不会保护这些。

答案 1 :(得分:0)

是的,这是正常的。请阅读:http://www.sqlite.org/lockingv3.html