SQLite3和多个进程

19 c sqlite concurrency

当多个进程访问单个SQLite数据库文件时,如何确保正确性?

laa*_*lto 16

首先,避免并发访问sqlite数据库文件.并发是sqlite的弱点之一,如果你有一个高度并发的应用程序,请考虑使用另一个数据库引擎.

如果您无法避免并发或删除sqlite,请将您的写入事务包装在BEGIN IMMEDIATE;...中END;.sqlite中的默认事务模式是DEFERRED指仅在第一次实际写入尝试时获取锁定.通过IMMEDIATE事务,可以SQLITE_BUSY立即获取锁定,或者立即获取锁定.当有人持有对数据库的锁定时,将导致其他锁定尝试SQLITE_BUSY.

处理SQLITE_BUSY是你必须自己决定的事情.对于许多应用程序,等待一两秒然后重试工作完全正常,n尝试失败后放弃.有一些sqlite3 API帮助程序使这很容易,例如sqlite3_busy_handler(),sqlite3_busy_timeout()但也可以手动完成.

您还可以使用操作系统级别同步来获取数据库的互斥锁,或使用操作系统级别的线程间/进程间消息传递来指示一个线程何时完成访问数据库.

  • DEFERRED 实际上意味着数据库在 BEGIN 语句之后通过读取或写入访问之前不会(共享)锁定(是的,它应该锁定读取)。IMMEDIATE 表示执行“BEGIN IMMEDIATE TRANSACTION”后立即锁定数据库。请参阅http://www.sqlite.org/lang_transaction.html (2认同)

sha*_*oth 5

如果任何 SQLite 原语尝试访问其他进程同时访问的数据库,它将返回 SQLITE_BUSY。您可以检查该错误代码并重复该操作。

或者,您可以使用操作系统同步 - MS Windows 上的互斥体或其他操作系统上的类似功能。该进程将尝试获取互斥锁,如果其他进程已经持有该互斥锁,则该进程将被阻塞,直到另一个进程完成操作并释放互斥锁。应注意防止进程获取互斥体然后永不释放它的情况。