SQLite 多线程——避免读者不必要的阻塞
SQLite multithread - avoid unnecessary blocking for readers
很久以前,我将使用相同 sqlite 数据库的 多线程应用程序 (php 脚本)上的所有事务打包到 BEGIN IMMEDIATE TRANSACTION
中。我记得,我在 SO 的某处读到:need to wrap all transactions with
BEGIN IMMEDIATEon multithread environment to avoid
SQLITE_BUSY` 状态。
现在,我正在考虑一些优化。
Sqlite 文档说:After a BEGIN IMMEDIATE, no other database connection will be able to write to the database or do a BEGIN IMMEDIATE. Other processes can continue to read from the database, however.
那么,只用 IMMEDIATE
包装 WRITE
交易也许是安全的(或任何陷阱)?并使用默认 "BEGIN TRANSACTION" 实时 READ
交易?或者也许检查我的代码,只避开 BEGIN IMMEDIATE
开始的地方,然后去写,然后读,然后写等等,然后重写这个圈子,比如:
BEGIN IMMEDIATE
ALL READS
then
ALL WRITES
END
如果我没记错的话,在后一种情况下,SQLite 只会在 WRITE
开始时锁定整个数据库,而不是在 BEGIN IMMEDIATE
星时锁定整个数据库?其他线程将能够读取并从那里开始 BEGIN IMMEDIATE
statements?
当两个事务想要将读锁升级为写锁时,可能会发生死锁。
为保证这种情况不会发生,至少其中一项交易必须使用 BEGIN IMMEDIATE
.
只读事务不涉及此类死锁(它们总是在不需要更多锁的情况下结束),因此它们可以使用 BEGIN DEFERRED.
您可以使用预写日志 (WAL)。 WAL 提供了更多的并发性,因为读者不会阻止作者,而作者也不会阻止读者。读和写可以同时进行。可以找到更多关于它的信息 here.
要在您的应用程序中启用它,请在连接字符串中使用 journal mode=WAL
或 PRAGMA journal_mode=WAL;
很久以前,我将使用相同 sqlite 数据库的 多线程应用程序 (php 脚本)上的所有事务打包到 BEGIN IMMEDIATE TRANSACTION
中。我记得,我在 SO 的某处读到:need to wrap all transactions with
BEGIN IMMEDIATEon multithread environment to avoid
SQLITE_BUSY` 状态。
现在,我正在考虑一些优化。
Sqlite 文档说:After a BEGIN IMMEDIATE, no other database connection will be able to write to the database or do a BEGIN IMMEDIATE. Other processes can continue to read from the database, however.
那么,只用 IMMEDIATE
包装 WRITE
交易也许是安全的(或任何陷阱)?并使用默认 "BEGIN TRANSACTION" 实时 READ
交易?或者也许检查我的代码,只避开 BEGIN IMMEDIATE
开始的地方,然后去写,然后读,然后写等等,然后重写这个圈子,比如:
BEGIN IMMEDIATE
ALL READS
then
ALL WRITES
END
如果我没记错的话,在后一种情况下,SQLite 只会在 WRITE
开始时锁定整个数据库,而不是在 BEGIN IMMEDIATE
星时锁定整个数据库?其他线程将能够读取并从那里开始 BEGIN IMMEDIATE
statements?
当两个事务想要将读锁升级为写锁时,可能会发生死锁。
为保证这种情况不会发生,至少其中一项交易必须使用 BEGIN IMMEDIATE
.
只读事务不涉及此类死锁(它们总是在不需要更多锁的情况下结束),因此它们可以使用 BEGIN DEFERRED.
您可以使用预写日志 (WAL)。 WAL 提供了更多的并发性,因为读者不会阻止作者,而作者也不会阻止读者。读和写可以同时进行。可以找到更多关于它的信息 here.
要在您的应用程序中启用它,请在连接字符串中使用 journal mode=WAL
或 PRAGMA journal_mode=WAL;