14

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

引用SQLite 文档

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

相反,SQLite Wiki条目说

不要在多个线程中同时使用同一个数据库连接

我尝试了一个示例应用程序,它产生数百个线程并共享一个 SQLite 句柄来读取和写入,它工作正常。

那么 SQLite wiki 条目是否已过时,或者 SQLite 可能无法使用同一连接同时处理来自不同线程的读取和写入?

4

2 回答 2

9

编辑

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

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

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

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

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

问候!

于 2012-07-31T12:16:13.837 回答
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 时,您可以从中获得更好的性能,那么使用连接池也是最好的选择。

于 2017-04-08T18:42:43.023 回答