sqlite鎖機制概述

2021-07-30 00:09:39 字數 2000 閱讀 8111

sqlite的鎖的粒度比較粗,是資料庫級別的,也就是說即使只是對某個頁進行讀寫操作,sqlite也會封鎖整個資料庫。這種策略降低了讀-寫事務和寫-寫事務間的併發程度,但是大大簡化了程式設計,減小了整個程式的大小。所以,sqlite的適用場景為:較少次寫入資料,大量、多次讀出資料。這也是sqlite作為一款嵌入式資料庫的設計初衷。

sqlite讀事務獲取鎖的過程:unlocked->pending->shared->進行讀取操作

sqlite寫事務獲取鎖的過程:unlocked->pending->shared->reserved->建立回滾日誌,在資料庫記憶體頁中寫入資料,重新整理日誌檔案到磁碟->pending->exclusive->重新整理記憶體頁中的資料到磁碟。

在windows平台,sqlite使用了lockfile(),lockfileex(),unlockfile(),unlockfileex()這幾個api實現鎖。鎖機制的實現是通過封鎖乙個在檔案1gb處的大小為512b的檔案頁內的位元組實現的。其中:

在其他一些平台上,shared_lock是通過對shared_size內的隨機的乙個位元組加鎖實現的,但是這種方法對併發性依然會有一定的影響。windows api lockfileex()支援對檔案的某一部分重複加鎖,所以只需要把shared_size內的所有位元組都用lockfileex()鎖住就可以了,簡化程式的同時提高了併發性。

sqlite通過引入pending_lock解決寫餓死問題。如果檔案當前的鎖狀態是pending,那麼在此之前已經申請到shared_lock的讀事務可以繼續執行,但是不允許新的事務申請shared_lock。當已經存在的讀事務執行完畢後,將pending_lock公升級為exclusive_lock,執行寫入操作。

也正是因為解決寫餓死引入了pending_lock,所以有了pending_lock和exclusive_lock之間互相等待導致的死鎖問題。

考慮如下的兩個事務:

b事務的insert語句獲取了reserved_lock,記憶體頁中的資料進行修改。此時a事務申請到了shared_lock,b事務完成修改後,公升級為pending_lock,為了申請到exclusive_lock,等待已經存在的a事務完成釋放shared_lock。但是a事務的下乙個語句是insert,a事務想要公升級為reserved_lock,但是因為b事務持有pending_lock,所以a事務要等待b事務完成後釋放pending_lock。這樣兩個事務互相等待對方完成,就陷入了死鎖。

sqlite用鎖超時的機制處理死鎖。當某個事務陷入死鎖後,sqlite嘗試一定次數,幾次之後依然無法獲取鎖的話,就返回錯誤資訊,把如何處理錯誤的權利交給使用者程式。sqlite提供了三種不同的事務型別共使用者選用: deferred,immediate,exclusive,它們獲取鎖的起點如圖所示:

基本的使用準則是:如果你在使用的資料庫沒有其它的連線,用begin就足夠了。但是,如果有其它的連線也要對資料庫進行寫操作,就得使用begin immediate或begin exclusive開始事務。

[1]

[2] 《inside sqlite》

[3]

sqlite 鎖機制 時間函式

在sqlite的使用過程中最常發生的資料庫異常便是資料庫被鎖定了 sqlite busy或者sqlite locked sqlite對於併發的處理機制是允許同乙個程序的多個執行緒同時讀取乙個資料庫,但是任何時刻只允許乙個執行緒 程序寫入資料庫。所以必須要必須要對資料庫的讀寫進行控制。sqlite資料...

SQLite資料庫的鎖機制

sqlite資料庫的鎖機制包括四種鎖,共享鎖 shared lock 預留鎖 reserved lock 和未決鎖 pending lock 排他鎖 exclusive lock 其中讀操作,用的是shared lock,所以併發的多個讀資料庫。如果有乙個讀操作存在,那麼都不會允許寫。而寫就比較麻煩...

SQLite入門一 SQLite概述

學習 掌握一門新的技術通常需要了解這門技術產生的背景,為什麼需要這樣的技術,或者說能夠解決那些問題?sqlite概述 sqlite特性 與其他資料庫比較 使用sqlite解決那些問題 sqlite概述 sqlite資料庫引擎具有獨立 無伺服器端 零配置 支援事務等特點,作為一款優秀的開源嵌入式資料庫...