2012-07-31 98 views
11

我有一個應用程序使用SQLite(版本3.7.2)來存儲數據。我有一個SQLite連接在多個線程之間共享,可以從同一個SQLite數據庫中讀寫。 SQLite使用DSQLITE_THREADSAFE = 1進行編譯,這意味着SQLite處於Serialized模式。SQLite:跨線程共享連接讀取和寫入

SQLite docs

序列化引用:在串行模式時,SQLite可以安全地由多個用於 線程沒有限制。

相反的SQLite Wiki詞條中說

不要使用超過 一個線程在同一時間同一個數據庫連接

我有一個示例應用程序產卵嘗試數百個線程和共享一個SQLite句柄來讀取&寫入工作正常。

SQLite wiki條目是過時的還是SQLite可能無法處理使用相同連接同時從不同線程讀取和寫入的情況?

回答

7

EDIT

DSQLITE_THREADSAFE = 2:多線程模式 術語 「多線程」 是SQLite中有點混亂。看起來像在多線程模式下,您不能與其他線程共享連接,因爲連接本身不會使用互斥鎖來阻止一個線程修改連接,而另一個線程正在使用它。

DSQLITE_THREADSAFE = 1:串行模式 然而,在串行模式下,它會鎖定數據文件,並且將使用互斥來控制用於共享連接的接入。

從文檔: ...當SQLite是與SQLITE_THREADSAFE = 1編譯SQLite庫將其本身序列訪問數據庫的連接,並準備語句,使應用程序可以自由地使用相同的數據庫連接或同一準備的語句在不同的線程中同時進行。

因此,隨着連接打交道時,系列化模式線程安全多線程模式不是,雖然你仍然可以有到同一數據庫的多個連接。

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

商祺!

+2

我讀到了,但我想知道維基是過時的還是SQLite連接現在支持來自多個線程的同一連接的'reads'和'writes'? – omggs 2012-07-31 14:36:56

+0

@omggs你是對的。這些術語在SQLite文檔中有點混淆。對我來說*多線程*和*序列化*是相同的,但它們不是。我使用序列化連接,但不在線程之間共享它們......現在我瞭解到它可以安全地共享:) – devundef 2012-07-31 16:17:45

+1

感謝您的確認! SQLite wiki確實過時了! – omggs 2012-08-01 04:04:43

0

這是一個壞主意,分享給一個以上的線程一個連接時,你有DSQLITE_THREADSAFE = 0

想象一下你的線程1執行此代碼:

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

和你的線程2在執行該代碼在同一時間:

1. connection.setAutoCommit(true); 

現在如果THREAD 2的指令1正好在THREAD 1的指令3之前執行,該怎麼辦?您可能會得到一個帶有「自動提交模式下的數據庫」消息的SQLException(因爲自動提交方法在同一個Connection對象上執行)。

這意味着一個應該同步他的代碼礦用DSQLITE_THREADSAFE = 1

使用連接池也將是最好的,如果你要多線程下發展的代碼從當你決定選擇另一個,你可以得到更好的性能DBMS。