【问题标题】:sqlite3: avoiding "database locked" collisionsqlite3:避免“数据库锁定”冲突
【发布时间】:2015-10-28 00:22:40
【问题描述】:

我在一个 cpu 上并行运行两个 python 文件,它们都使用同一个 sqlite3 数据库。我正在使用 sqlalchemy 处理 sqlite3 数据库,我的理解是 sqlalchemy 在一个应用程序中处理所有线程数据库问题。我的问题是如何处理来自两个不同应用程序的访问? 我的两个程序之一是烧瓶应用程序,另一个是不时更新数据库的 cronjob。 似乎即使是 sqlite 数据库上的只读任务也会锁定数据库,这意味着如果两个应用程序要同时读取或写入,我会收到错误。

OperationalError: (sqlite3.OperationalError) database is locked

假设我的 cronjob 应用每 5 分钟运行一次。如何确保我的两个应用程序之间没有冲突?我可以在访问数据库之前检查的文件中写入一些读取标志,但在我看来应该有一个标准的方法来做到这一点? 此外,我正在使用 gunicorn 运行我的应用程序,原则上可以运行多个作业......所以我最终希望我的烧瓶应用程序有 2 个以上的并行作业...... 谢谢 卡尔

【问题讨论】:

  • 您可以使用锁定文件,但您的问题会随着访问数据库的线程数增加而增加。我建议使用数据库服务器(MySQL、PostgresQL...)而不是 SQlite。
  • 是的,SQLite 并不是真正为这个用例设计的。 @克劳斯D。是正确的,你需要更换它。
  • 我使用 Flask+sqlite 和一个任务队列,它也可以毫无问题地与数据库通信。 SQLite 可以在多个线程/进程中使用。
  • hi coleifer...你能解释一下你的任务队列系统吗?
  • 一切都很简单。这些任务由一个持续运行的 Python 程序执行,该程序监听事件。每当运行任务时,它都会连接到数据库,然后在返回/错误时关闭连接。 Web 应用打开请求连接,然后在响应时关闭它。

标签: python database sqlite gunicorn


【解决方案1】:

这是真的。 Sqlite 不是为这种应用程序构建的。 Sqlite 真正适用于轻量级的单线程、单实例应用程序。

Sqlite 连接是每个实例一个,如果您开始使用某种线程多路复用器(请参阅https://www.sqlite.org/threadsafe.html),这是可能的,但它的麻烦多于它的价值。还有其他提供该功能的解决方案——看看 Postgresql 或 MySQL。这些数据库是开源的,有很好的文档记录,得到很好的支持,并且支持您需要的并发类型。

【讨论】:

【解决方案2】:

我不确定 SQLAlchemy 如何处理连接,但如果您使用的是 Peewee ORM,那么解决方案非常简单。

当您的 Flask 应用发起请求时,您将打开与数据库的连接。然后当 Flask 发送响应时,你关闭数据库。

同样,在您的 cron 脚本中,当您开始使用数据库时打开一个连接,然后在进程完成时关闭它。

您可能会考虑的另一件事是在 WAL 模式下使用 SQLite。这可以提高并发性。当您打开连接时,您可以使用 PRAGMA 查询设置日志模式。

欲了解更多信息,请参阅http://charlesleifer.com/blog/sqlite-small-fast-reliable-choose-any-three-/

【讨论】:

    猜你喜欢
    • 2011-05-05
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2012-07-12
    • 1970-01-01
    • 2015-11-22
    相关资源
    最近更新 更多