【问题标题】:SQLite3 and multiple processesSQLite3 和多个进程
【发布时间】:2010-11-06 23:59:02
【问题描述】:

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

【问题讨论】:

  • 至少你可以用适当的编程语言标记你的问题。
  • 是的,或者指定您需要一种与语言无关的平台与一切无关的方法。
  • 我会尝试在没有“显示代码”的情况下再次询问...
  • 对不起,我是盲人... 选择的程序语言是 C/C++。
  • 这是我在这里的第一篇文章,希望我能从这个错误中学习如何制作适当的标签。

标签: c sqlite concurrency


【解决方案1】:

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

在你使用的 SQLite 中

开始交易

提交交易

配对来界定您的交易。将您的 SQL 代码放在两者之间,以便在单个事务中执行。

但是,正如之前的人在我之前评论的那样 - 您需要密切注意并发问题。如果 SQLite 用于读取访问,它可以相当快地工作(多个读取器不会被阻塞并且可以同时运行)。

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

【讨论】:

    【解决方案2】:

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

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

    处理SQLITE_BUSY 是您必须自己决定的事情。对于许多应用程序来说,等待一两秒钟然后重试完全没问题,在n 尝试失败后放弃。有 sqlite3 API 助手可以让这变得简单,例如sqlite3_busy_handler()sqlite3_busy_timeout() 但也可以手动完成。

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

    【讨论】:

    • 我知道必须在一个进程中使用事务。但是,我的情况是,与多个线程相比,我有多个进程同时访问同一个数据库。 SQLite 事务真的能处理这样的并发吗!?!?
    • @Tom:是的,在 sqlite3 操作系统特定的移植层中,有跨进程工作的锁定功能。更多信息请参见sqlite.org/lockingv3.html
    • DEFERRED 实际上意味着数据库不会(共享)锁定,直到在 BEGIN 语句之后通过读取或写入访问它(是的,它应该锁定读取)。 IMMEDIATE 表示在执行“BEGIN IMMEDIATE TRANSACTION”后立即锁定数据库。见sqlite.org/lang_transaction.html
    • 并发这个词应该可以和并行互换。
    【解决方案3】:

    关于 this 的 SQLite 常见问题解答

    【讨论】:

    • 在我在这里发布我的问题之前阅读了该常见问题解答。我当然应该这么说(这是我今天学到的第二课)。我不明白他们到底是什么意思。我应该自己处理所有锁定的东西,还是 SQLite 支持它? “当任何进程想要写入时,它必须在更新期间锁定整个数据库文件。但这通常只需要几毫秒。其他进程只是等待写入者完成,然后继续他们的业务。”为自己实现这一点需要一些努力。
    • 不仅乏味,而且容易出错。我希望 SQLite 有必要的支持,在这种情况下,我想知道我应该使用哪些功能。附带说明一下,我认为 SQLite 的文档在涉及源代码示例时有点过于拘束......
    【解决方案4】:

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

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

    【讨论】:

    • 嗯,SQLite不提供锁来保护数据库文件访问吗??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多