SQLite非独占的RESERVED锁?

时间:2008-11-15 00:43:32

标签: sqlite concurrency locking reserved

我一直在寻求改善网站的SQLite性能,特别是在交易方面。从本质上讲,我正在寻找的是一种在一个过程中推迟数据库写入的方法,以便它们可以一次完成。但是,当我正在累积更新查询时,我希望其他进程能够同时读取和写入数据库,并且只有在进程中发出提交时才锁定文件以进行写入。

在查看文档时,似乎一旦在事务中发出更新命令,进程就会获得一个RESERVED锁,如果我没记错的话,这意味着任何其他尝试添加更新查询的进程它自己的事务或提交事务无法这样做,因此阻塞直到事务提交锁进程。

我确信这个特定功能有很好的数据完整性原因。我只能说,在我的情况下,同时执行这些更新没有任何危险。

一个解决方案是,在每个进程中,我可以累积我希望在数组中调用的查询的文本,然后在我准备写入时循环它,但我想知道SQLite事务是否可以我会自动为我做这件事。

更新:当我说“立即执行所有更新”时,我的意思实际上是使用SQLite中的事务来获取每个进程一次EXCLUSIVE锁并写入磁盘,而不是每次执行一次查询。这导致使用SQLite加速100倍。

我已经完成了一些基本的测试,似乎一旦你有多个进程向他们的事务添加查询,一旦你点击更新查询,该进程试图获得RESERVED锁。由于只有一次进程可以拥有保留锁,这意味着尝试获取锁的任何其他进程都将阻塞,直到带锁的进程完成事务。

我承认这个问题可能是一个过早的优化,因为我还没有遇到任何性能损失,但我已经运行了一些简单的测试,每个创建和运行100个查询的事务的100个用户在PHP上花费大约4秒我的机器。

2 个答案:

答案 0 :(得分:3)

SQLite支持ATTACH将一个数据库附加到另一个数据库。也许您可以在单独的数据库中累积数据,并且在准备好合并累积的行时,附加单独的数据库,在单个语句中复制行并分离。

编辑:对OP的类似建议是在sqlite用户的mailing list thread进行的,并进行了一些后续讨论。

答案 1 :(得分:1)

最好是附加数据库只是创建一个临时表。 (创建临时......)

看看新的WAL日志模式,它可以实现你手动完成的任务,它允许同时写入和读取(尽管不是同时写入)。

#pragma journal_mode = WAL