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

时间:2012-07-31 11:43:39

标签: multithreading sqlite c-api

我有一个使用SQLite(版本3.7.2)来存储数据的应用程序。我在多个线程之间共享一个SQLite连接,它从同一个SQLite数据库中写入和读取。 SQLite使用DSQLITE_THREADSAFE = 1编译,这意味着SQLite处于序列化模式。

引自SQLite docs

  

序列化:在序列化模式下,SQLite可以被多个安全使用   线程没有限制。

相反,SQLite Wiki条目说

  

不要同时使用相同的数据库连接   一个线程

我尝试使用一个示例应用程序来生成数百个线程并共享一个SQLite句柄来读取&写哪个工作正常。

SQLite wiki条目是否过时或者SQLite可能无法使用相同的连接同时处理来自不同线程的读写操作?

2 个答案:

答案 0 :(得分:8)

修改

DSQLITE_THREADSAFE = 2 :多线程模式 术语“多线程”在SQLite中有点混淆。似乎在多线程模式下,您无法与其他线程共享连接,因为连接本身不会使用互斥锁来阻止一个线程在另一个线程正在使用它时修改连接。

DSQLITE_THREADSAFE = 1 :序列化模式 但是,在序列化模式下,它将锁定数据文件并使用互斥锁来控制共享连接的访问​​。

来自docs: ...当使用SQLITE_THREADSAFE = 1编译SQLite时,SQLite库本身将序列化对数据库连接和预处理语句的访问,以便应用程序可以在不同的线程中同时使用相同的数据库连接或相同的预准备语句。

因此,在处理连接时,序列化模式 线程安全多线程模式不是,尽管你仍然可以拥有多个连接到同一个数据库。

来源:http://www.sqlite.org/c3ref/c_config_getmalloc.html#sqliteconfigmultithread

问候!

答案 1 :(得分:0)

当您拥有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时,可以从中获得更好的性能。