Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQLite数据库已被锁定 我有一段代码在C++中创建了很多线程,每个线程访问一个通用SQLite数据库并选择和插入数据。_C++_Multithreading_Sqlite - Fatal编程技术网

SQLite数据库已被锁定 我有一段代码在C++中创建了很多线程,每个线程访问一个通用SQLite数据库并选择和插入数据。

SQLite数据库已被锁定 我有一段代码在C++中创建了很多线程,每个线程访问一个通用SQLite数据库并选择和插入数据。,c++,multithreading,sqlite,C++,Multithreading,Sqlite,所有插入都在事务中使用。很多时候,我得到“数据库被锁定”错误 如何解决这个问题?我主要是想指出,正如一些人所设想的那样,您不应该让多个用户写入同一个SQLite DB,因为这不是它的设计目的 (5) 可以使用多个应用程序或同一应用程序的多个实例吗 应用程序是否同时访问单个数据库文件 多个进程可以同时打开同一个数据库。 多个进程可以同时进行选择。但只是 一个进程可以在任何时候对数据库进行更改 然而,时间 SQLite使用读写器锁来控制对数据库的访问。 (在不支持读写器锁的Win95/98/ME下

所有插入都在事务中使用。很多时候,我得到“数据库被锁定”错误


如何解决这个问题?

我主要是想指出,正如一些人所设想的那样,您不应该让多个用户写入同一个SQLite DB,因为这不是它的设计目的

(5) 可以使用多个应用程序或同一应用程序的多个实例吗 应用程序是否同时访问单个数据库文件

多个进程可以同时打开同一个数据库。 多个进程可以同时进行选择。但只是 一个进程可以在任何时候对数据库进行更改 然而,时间

SQLite使用读写器锁来控制对数据库的访问。 (在不支持读写器锁的Win95/98/ME下 使用概率模拟代替。)但要小心:这 如果数据库文件不可用,锁定机制可能无法正常工作 保存在NFS文件系统上。这是因为fcntl()文件锁定 在许多NFS实现中都存在漏洞。您应该避免放置SQLite NFS上的数据库文件,如果多个进程可能尝试访问 同时归档。在Windows上,微软的文档说 如果您没有运行 Share.exe守护进程。对Windows有丰富经验的人 告诉我,网络文件的文件锁定是非常有缺陷的,而不是 可靠的。如果他们说的是真的,共享SQLite数据库 在两台或多台Windows计算机之间切换可能会导致意外问题

我们知道没有其他嵌入式SQL数据库引擎支持as 与SQLite一样多的并发性。SQLite允许多个进程具有 数据库文件一次打开,并供多个进程读取 立即建立数据库。当任何进程想要写入时,它必须锁定 更新期间的整个数据库文件。但通常情况下 只需要几毫秒。其他进程只是等待编写器 完成后继续他们的业务。其他嵌入式SQL 数据库引擎通常只允许单个进程连接到 立即打开数据库

但是,客户端/服务器数据库引擎(如PostgreSQL、MySQL或 Oracle)通常支持更高级别的并发并允许 多个进程同时写入同一数据库 时间这在客户机/服务器数据库中是可能的,因为 始终有一个控制良好的服务器进程可用于协调 通道如果您的应用程序需要大量的并发性,那么 您应该考虑使用Client/Server数据库。但是经验 这表明大多数应用程序需要的并发性比它们的应用程序少得多 设计师想象

当SQLite试图访问被另一个进程锁定的文件时, 默认行为是返回SQLITE_BUSY。你可以调整这个 C代码中的行为 使用sqlite3\u busy\u handler()或sqlite3\u busy\u timeout()API函数

来源:

您可以以多线程的方式使用SQLite,但是对于每个线程,您必须打开一个新连接(
sqlite3\u open()
)并在该连接上操作


如果您仅在多个线程上使用“开始”启动事务,并且使用INSERTs sqlite时可能会死锁,那么

中会有更多信息

这是因为sqlite只在BEGIN上获得读取锁。在INSERT上,它必须将读锁升级为写锁(只有在没有读锁的情况下才可以这样做)。 日志模式=WAL(仅默认日志模式=delete)不会发生这种情况,因为WAL模式允许在写入期间进行读取访问。(因此,使用WAL模式可能是一个解决方案)

解决方案:
如果计划在事务中使用插入,请使用“立即开始”。这样sqlite就可以在数据库上获得写锁。

false,它使用多线程/多连接。看见