我有一个使用SQLite(3.7.2版)存储数据的应用程序。我有一个在多个线程之间共享的SQLite连接,这些线程从同一个SQLite数据库进行写入和读取。SQLite是在DSQLITE_THREADSAFE=1的情况下编译的,这意味着SQLite处于序列化模式。
引用SQLite文档
序列化:在序列化模式下,SQLite可以由多个线程没有限制。
相反,SQLite Wiki条目显示
在超过单线程
我尝试了一个示例应用程序,它产生了数百个线程,并共享一个SQLite句柄来读取&写哪一个运行良好。
那么,SQLite wiki条目是否已经过时,或者SQLite可能无法使用相同的连接同时处理来自不同线程的读写?
编辑
DSQLITE_THREADSAFE=2:多线程模式术语"多线程"在SQLite中有点混淆。似乎在多线程模式下,你不能与其他线程共享连接,因为连接本身不会使用互斥来阻止一个线程在另一个线程使用连接时修改连接。
DSQLITE_THREADSAFE=1:序列化模式但是,在序列化模式下,它将锁定数据文件,并使用互斥来控制对共享连接的访问。
来自文档:…当使用SQLite_THREADSAFE=1编译SQLite时,SQLite库本身将序列化对数据库连接和准备好的语句的访问,以便应用程序可以在不同的线程中自由使用相同的数据库连接或相同的准备好的声明。
因此,在处理连接时,序列化模式是线程安全,但多线程模式不是,尽管您仍然可以有多个到同一数据库的连接。
来源:http://www.sqlite.org/c3ref/c_config_getmalloc.html#sqliteconfigmultithread
问候!
当DSQLITE_THREADSAFE=0 时,在多个线程之间共享一个连接是个坏主意
想象一下,THREAD 1正在执行以下代码:
1. connection.setAutoCommit(false);
2. statement.executeUpdate(sql);
3. connection.commit();
并且THREAD 2同时执行此代码:
1. connection.setAutoCommit(true);
现在,如果THREAD 2的指令1正好在THREAD 1的指令3之前执行,该怎么办?您可能会得到一个带有消息"数据库处于自动提交模式"的SQLException(因为自动提交方法是在同一个Connection对象上执行的)。
这意味着在使用DSQLITE_THREADSAFE=1 之前应该同步他的代码
如果你想开发多线程代码,那么使用连接池也是最好的,当你决定选择另一个DBMS时,你可以从中获得更好的性能。