2010-11-04 379 views
6

我有使用SQLite(3.7.3)避免sqlite3的數據庫鎖定

我打的數據庫鎖定錯誤,這似乎是相當普遍的多線程應用程序。 我想知道如何避免它在我的情況。

讓我來描述一下我正在建造的東西。對不起,沒有代碼太大又複雜。

我有大約8個線程同時訪問數據庫。這些線程中的任何一個都可以同時讀取或寫入。

數據庫表中的每一行都有一個文件路徑,指向一個資源+與該資源相關的其他屬性。

3個值得注意的領域是讀者,狀態和del。

讀者是每個線程從資源讀取時間增加,但只有當狀態> 0,德爾= 0

讓我有些SQL,做

UPDATE resource set readers=readers+1 where id=? AND del=0 AND status>0 

在那之後,我檢查更新的行數。它應該只有1. 之後,我嘗試用select讀取行。我這樣做,即使它不能更新 ,因爲我需要知道它失敗的原因。

我嘗試在事務中包裝更新和選擇,但沒有幫助。 我已經檢查過,我也打電話給我的發言。

現在,我認爲sqlite默認序列化。我嘗試了幾個開放模式,但我仍然得到相同的錯誤。

在你問之前,不,我不打算去mysql。我絕對需要零配置。

有人可以提供一些關於如何避免這種類型的問題的指針嗎?我應該將閱讀器鎖定在數據庫之外嗎?如果我這樣做,我應該用什麼機制來替代它?我在C++下使用Linux,並使用boost庫。

編輯: 有趣的是,在更新後的呼叫中添加COMMIT可以大大改善事情。

+1

提交更經常可以在數據庫文件上實現更細粒度的EXCLUSIVE鎖,這將減少讀者在表中等待解鎖的時間。這是以增加的日誌文件開銷爲代價的。查看http://sqlite.org/lockingv3.html#writing瞭解更多信息。 – checker 2014-02-20 23:58:28

回答

1

當您打開數據庫,你應該配置「忙超時」

int sqlite3_busy_timeout(sqlite3*, int ms); 

http://www.sqlite.org/c3ref/busy_timeout.html

+2

嗨,是的,我試過了。它有一點幫助。但即使設置爲1秒鐘,它仍然會遇到鎖定問題。我已啓用shared_cache模式,這似乎有助於比繁忙的超時。我會嘗試兩種。 – Matt 2010-11-04 22:22:09

+0

原來,對於我的應用程序來說,sqlite正在遭受嚴重打擊。所以我把閱讀器領域轉移到了記憶中。這已經提高了大約10000%的性能,而且我的硬盤更少了。 – Matt 2010-11-08 21:13:52

1

第一個問題:你想使用所有八個線程一個連接?如果是這樣,請確保每個線程都有自己的連接。我不知道任何喜歡這個的數據庫。

還檢查了常見問題解答:http://www.sqlite.org/faq.html

顯然的SQLite必須設置爲1,他們確實有一種方法來確定,如果這是你的問題SQLITE_THREADSAFE預處理程序選項進行編譯。

另一個問題是寫入只能從一個進程安全地發生。

+0

是的,每個線程一個連接。我將檢查線程安全預處理器選項。儘管如此,我的印象是默認的。 – Matt 2010-11-04 22:41:08

+0

我如何設置此選項? – ademar111190 2013-01-17 14:43:31