我们将Recess 框架用于 Web 服务。作为其中的一部分,我们使用 Recess 的缓存机制,作为 SQLite 数据库提供。
我们已经愉快地使用这种缓存机制大约一年了。然而,现在有 3 次我们遇到了 SQLite 数据库被“锁定”并导致问题的问题。我们得到的消息是“异常 'PDOException' 和消息 'SQLSTATE[HY000]:一般错误:5 数据库被锁定'在......”。
我进行了搜索,这似乎是一个常见问题,并且有很多关于如何将其可能性降到最低或防止它的讨论(例如,drupal 委员会)。但是,我的问题似乎与此略有不同。我所描述的情况似乎表明它与并发有关 - 当两个 PHP 进程试图同时访问 SQLite 数据库时,其中一个进程会出现锁定错误。在这种情况下,努力将问题最小化是有意义的。但是对于我的应用程序,当问题开始发生时(可能是因为并发性),SQLite 数据库从那时起永久锁定。从此时起,每一个缓存访问请求都会得到一个 PDOException。我们的解决方案是只删除缓存文件,这不是世界末日,但这需要人工干预,而且意味着我们会丢失构建的缓存数据。
为什么会发生这种情况?是否还有其他原因可以让我们一开始就获得锁?为什么锁会持续存在?有没有办法以编程方式清除它?有没有办法从一开始就阻止它?
到目前为止,我正在考虑的两个“解决方案”是:
- 在缓存访问函数周围放置一个 try-catch。如果我们得到异常,只需忽略缓存并通知技术支持手动清除缓存。
- 对 SQLite 文件使用互斥锁(使用PHP flock)来防止并发问题(但同样,我什至不确定这是根本原因)。
任何信息或建议将不胜感激!