C SQLite3和多进程

C SQLite3和多进程,c,sqlite,concurrency,C,Sqlite,Concurrency,当多个进程访问单个SQLite数据库文件时,如何确保正确性?如果任何SQLite原语试图访问其他进程同时访问的数据库,则它将返回SQLite\u BUSY。您可以检查该错误代码,然后重复该操作 或者,您可以在MS Windows上使用操作系统同步-互斥,或者在其他操作系统上使用类似的东西。进程将尝试获取互斥体,如果其他进程已经持有互斥体,则进程将被阻止,直到其他进程完成操作并释放互斥体。应注意防止进程获取mutext后再也不释放它。首先,避免并发访问sqlite数据库文件。并发是SQLite的弱

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

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


或者,您可以在MS Windows上使用操作系统同步-互斥,或者在其他操作系统上使用类似的东西。进程将尝试获取互斥体,如果其他进程已经持有互斥体,则进程将被阻止,直到其他进程完成操作并释放互斥体。应注意防止进程获取mutext后再也不释放它。

首先,避免并发访问sqlite数据库文件。并发是SQLite的弱点之一,如果您有一个高度并发的应用程序,请考虑使用另一个数据库引擎。 如果无法避免并发或删除sqlite,请将写事务包装在
beginimmediate中<代码>结束。sqlite中的默认事务模式是延迟的,这意味着只有在第一次实际写入尝试时才获取锁。使用
IMMEDIATE
事务,可以立即获取锁,或者立即获得
SQLITE\u BUSY
。当有人持有数据库锁时,其他锁定尝试将导致
SQLITE\u BUSY

处理
SQLITE\u BUSY
是你必须自己决定的事情。对于许多应用程序来说,等待一两秒钟,然后重试就可以了,在尝试失败后放弃。有一些sqlite3 API帮助程序可以简化这一过程,例如
sqlite3\u busy\u handler()
sqlite3\u busy\u timeout()
,但也可以手动完成


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

SQLite FAQ关于确切的问题。

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

在SQLite中,您正在使用

开始交易

提交事务

配对以分隔事务。将SQL代码放在两者之间,以便在单个事务中执行

然而,正如前面的人所评论的,您需要密切关注并发性问题。如果将SQLite用于读访问(多个读卡器不会被阻塞,并且可以并发运行),则SQLite可以相当快地工作


但是,如果代码交替进行写访问和读访问,则情况会发生很大变化。使用SQLite-即使只有一个编写器处于活动状态,您的整个数据库文件也将被锁定。

至少您可以使用适当的编程语言标记您的问题。是的,或者指定您需要一种语言不可知的平台不可知的一切不可知的方法。我会尝试在不显示代码的情况下再次询问……对不起,我在家瞎了。。。选择的程序语言是C/C++。这是我在这里的第一篇文章,我希望学习如何从这个错误中做出适当的标记。嗯,SQLite不提供锁来保护数据库文件访问吗?我知道必须在一个进程中使用事务。但是,我的情况是,与多个线程不同,我有多个进程同时访问同一个数据库。SQLite事务真的能处理这样的并发吗@Tom:是的,在sqlite3操作系统特定的移植层中,有一个跨进程的锁定功能。请参阅for moredferred实际上意味着数据库在BEGIN语句之后被读或写访问之前(共享)不会被锁定(是的,它应该锁定读)。立即意味着在执行“开始立即事务”后立即锁定数据库。请看,并发这个词可能应该与并行性互换。在我将问题发布到这里之前,我阅读了常见问题解答。我当然应该这么说(这是我今天学到的第二课)。我不明白他们到底是什么意思。我是应该自己处理所有锁定的东西,还是SQLite支持它?“当任何进程想要写入时,它必须在其更新期间锁定整个数据库文件。但这通常只需要几毫秒。其他进程只需等待写入程序完成,然后继续处理它们的业务。”我自己要实现这一点需要一些努力。这不仅繁琐,而且容易出错。我希望SQLite有必要的支持,在这种情况下,我想知道我应该使用什么函数。作为补充说明,我认为SQLite的文档在涉及源代码示例时有点过于拘束。。。