在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)
答案 0 :(得分:2)
第二个事务在第一个事务释放其写锁定之前无法完成,第一个事务无法完成,直到第二个事务释放其读锁定。因此有意义的是立即回滚第二个,因为它无法在任何时间内完成,所以第一个可以完成,你可以再试一次。
BEGIN EXCLUSIVE
立即获取排他锁,而不是等待第一个查询,这解释了您看到的差异。
在事务中,您应该注意锁定的数据库(SQLITE_BUSY
),如果发生这种情况,请回滚并再试一次。超时忙处理程序不会保护这些。
答案 1 :(得分:0)
是的,这是正常的。请阅读:http://www.sqlite.org/lockingv3.html