我们的系统正在遭受这个问题,它肯定不是一个权限问题,因为程序本身可以打开数据库作为可写的许多线程的大多数时间,但偶尔(只有在 Windows 上,而不是在 OSX 上) ,一个线程会得到这些错误,即使所有其他线程在程序没有困难。
我们最终发现,失败的线程只是那些在另一个线程关闭数据库后立即试图打开数据库的线程(在3毫秒内)。我们推测这个问题是由于 Windows (或者 Windows 下的 sqlite 实现)并不总是在关闭文件时立即清理文件资源。我们通过在打开数据库时对其运行一个测试写查询(例如,创建然后删除一个名称愚蠢的表)来解决这个问题。如果创建/删除失败,我们将等待50毫秒并再次尝试,重复直到成功或经过5秒钟。
/* Return true if table pTab is read-only.
**
** A table is read-only if any of the following are true:
**
** 1) It is a virtual table and no implementation of the xUpdate method
** has been provided
**
** 2) It is a system table (i.e. sqlite_master), this call is not
** part of a nested parse and writable_schema pragma has not
** been specified
**
** 3) The table is a shadow table, the database connection is in
** defensive mode, and the current sqlite3_prepare()
** is for a top-level SQL statement.
*/
如果 <db_name>.sqlite-journal文件与 DB 文件存在于同一个文件夹中,这意味着您的 DB 当前打开,并且正在进行一些更改(或者在复制 DB 文件夹时已经打开)。如果您尝试打开数据库在这个时候错误 attempt to write a readonly database(或类似)可能会出现。