SQLite3和多个进程

时间:2009-06-30 12:40:19

标签: c sqlite concurrency

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

4 个答案:

答案 0 :(得分:15)

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

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

处理SQLITE_BUSY是您必须自己决定的事情。对于许多应用程序,等待一两秒然后重试工作完全正常,在n次尝试失败后放弃。有一些sqlite3 API助手可以轻松实现这一点,例如: sqlite3_busy_handler()sqlite3_busy_timeout(),但也可以手动完成。

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

基本上,您需要使用事务包装数据访问代码。这将使您的数据保持一致。不需要其他任何东西。

在SQLite中你正在使用

BEGIN TRANSACTION

COMMIT TRANSACTION

用于分隔您的交易。将SQL代码置于其间,以便在单个事务中执行。

然而,正如之前的人在我之前评论过 - 你需要密切注意并发问题。如果用于读取访问,SQLite可以合理地快速工作(多个读取器不被阻止并且可以并发运行)。

然而 - 如果您的代码交错写入和读取访问,则图片会发生相当大的变化。使用SQLite - 即使单个编写器处于活动状态,您的整个数据库文件也将被锁定。

答案 3 :(得分:0)

关于this

的SQLite常见问题解答