【问题标题】:Concurrent writes with SQLite and Peewee使用 SQLite 和 Peewee 进行并发写入
【发布时间】:2014-03-22 05:12:19
【问题描述】:

我计划将 SQLite 和 Peewee (ORM) 用于轻型内部 Web 服务(每秒

SQLite FAQ 表示允许并发读取,但来自多个线程的并发写入需要获取文件锁。我的问题是:Peewee 是否为我处理了这种锁定,或者我需要在我的代码中做些什么来使这成为可能?

Peewee 数据库对象在线程之间共享。我假设这意味着数据库连接也是共享的。

我找不到 Peewee 的具体答案,所以我在这里问。

【问题讨论】:

    标签: python multithreading sqlite concurrency peewee


    【解决方案1】:

    考虑在 1 个异步进程中运行所有写入操作。这使得当今的 Javascript 服务器编程如此著名(尽管这个想法的了解要长得多)。它只需要你对回调的异步编程概念有点熟悉:

    对于 SQLITE:

    适用于任何数据库。

    考虑在 python 中编写自己的瘦异步处理程序, 在这里解决,例如 SQLAlchemy + Requests Asynchronous Pattern 我会向您推荐最后一种方法,因为这可以让您获得更多的代码可移植性、可控性、独立于后端数据库引擎和可扩展性。

    【讨论】:

    • 披露:我是 APSW 的作者。 asyncvfs 早已过时。处理写入负载的推荐方法是使用 WAL(预写日志记录)。写入仍然是序列化的(到 WAL),但不会阻塞读取器。 sqlite.org/wal.html
    【解决方案2】:

    Sqlite 是执行锁定的,虽然我可以看出您可能会感到困惑——FAQ 的措辞有点模棱两可:

    当任何进程想要写入时,它必须在更新期间锁定整个数据库文件。但这通常只需要几毫秒。其他流程只是等待作者完成,然后继续他们的业务。其他嵌入式 SQL 数据库引擎通常只允许单个进程一次连接到数据库。

    因此,如果您有两个线程,每个线程都有自己的连接,并且一个获取写锁,那么另一个线程必须等待锁被释放才能开始写入。

    查看 pysqlite,默认的忙超时时间为 5 秒,因此第二个线程应等待最多 5 秒,然后再引发 OperationalError

    另外,我建议使用threadlocals=True 实例化您的 SqliteDatabase。这将存储每个线程的连接。

    【讨论】:

      猜你喜欢
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      相关资源
      最近更新 更多