SQLite:跨线程共享连接以进行读写

xpszyzbs  于 2023-10-23  发布在  SQLite
关注(0)|答案(2)|浏览(160)

我有一个使用SQLite(版本3.7.2)存储数据的应用程序。我有一个在多个线程之间共享的SQLite连接,它从同一个SQLite数据库进行读写。SQLite是用DSQLITE_THREADSAFE=1编译的,这意味着SQLite处于串行化模式。
引用自SQLite docs
序列化:在序列化模式下,SQLite可以安全地由多个线程使用,没有任何限制。
相反,SQLite Wiki条目说,
不要在多个线程中同时使用同一个数据库连接
我尝试了一个示例应用程序,它产生了数百个线程,并共享一个SQLite句柄来读写,运行良好。
那么是SQLite wiki条目过时了,还是SQLite可能无法处理使用相同连接同时从不同线程发生的读写?

ruyhziif

ruyhziif1#

编辑
DSQLITE_THREADSAFE=2:多线程模式术语“多线程”在SQLite中有点混乱。看起来在多线程模式下,你不能与其他线程共享一个连接,因为连接本身不会使用互斥来防止一个线程在另一个线程使用它时修改连接。
DSQLITE_THREADSAFE=1:但是,在serialized模式下,它将锁定数据文件,并使用互斥锁来控制共享连接的访问。

来自docs:当使用SQLITE_THREADSAFE=1编译SQLite时,SQLite库本身将序列化对数据库连接和准备语句的访问,以便应用程序可以自由地同时在不同的线程中使用相同的数据库连接或相同的准备语句。
因此,在处理连接时,* 序列化模式 * 是 * 线程安全的 *,但 * 多线程 * 模式不是,尽管你仍然可以有多个连接到同一个数据库。
来源:http://www.sqlite.org/c3ref/c_config_getmalloc.html#sqliteconfigmultithread

du7egjpx

du7egjpx2#

当DSQLITE_THREADSAFE=0时,在多个线程之间共享一个连接是一个坏主意
假设你的线程1正在执行以下代码:

1. connection.setAutoCommit(false);
2. statement.executeUpdate(sql);
3. connection.commit();

同时你的线程2也在执行这段代码:

1. connection.setAutoCommit(true);

现在,如果线程2的指令1正好在线程1的指令3之前执行,会怎么样?您可能会得到一个SQLException,消息是“databaseinauto-commit mode”(因为自动提交方法是在同一个Connection对象上执行的)。
这意味着应该使用DSQLITE_THREADSAFE=1同步代码
如果你要开发多线程代码,当你决定选择另一个DBMS时,使用连接池也是最好的选择。

相关问题