一、概述:
在sqlite中,鎖和併發控制機制都是由pager_module模組負責處理的,如acid(atomic, consistent, isolated, and durable)。在含有資料修改的事務中,該模組將確保或者所有的資料修改全部提交,或者全部回滾。與此同時,該模組還提供了一些磁碟檔案的記憶體cache功能。
事實上,pager_module模組並不關心資料庫儲存的細節,如b-tree、編碼方式、索引等,它只是將其視為由統一大小(通常為1024位元組)的資料塊構成的單一檔案,其中每個塊被稱為乙個頁(page)。在該模組中頁的起始編號為1,即第乙個頁的索引值是1,其後的頁編號以此類推。
二、檔案鎖:
在sqlite的當前版本中,主要提供了以下五種方式的檔案鎖狀態。
1). unlocked:
檔案沒有持有任何鎖,即當前資料庫不存在任何讀或寫的操作。其它的程序可以在該資料庫上執行任意的讀寫操作。此狀態為預設狀態。
2). shared:
在此狀態下,該資料庫可以被讀取但是不能被寫入。在同一時刻可以有任意數量的程序在同乙個資料庫上持有共享鎖,因此讀操作是併發的。換句話說,只要有乙個或多個共享鎖處於活動狀態,就不再允許有資料庫檔案寫入的操作存在。
3). reserved:
假如某個程序在將來的某一時刻打算在當前的資料庫中執行寫操作,然而此時只是從資料庫中讀取資料,那麼我們就可以簡單的理解為資料庫檔案此時已經擁有了保留鎖。當保留鎖處於活動狀態時,該資料庫只能有乙個或多個共享鎖存在,即同一資料庫的同一時刻只能存在乙個保留鎖和多個共享鎖。在oracle中此類鎖被稱之為預寫鎖,不同的是oracle中鎖的粒度可以細化到表甚至到行,因此該種鎖在oracle中對併發的影響程式不像sqlite中這樣大。
4). pending:
pending鎖的意思是說,某個程序正打算在該資料庫上執行寫操作,然而此時該資料庫中卻存在很多共享鎖(讀操作),那麼該寫操作就必須處於等待狀態,即等待所有共享鎖消失為止,與此同時,新的讀操作將不再被允許,以防止寫鎖飢餓的現象發生。在此等待期間,該資料庫檔案的鎖狀態為pending,在等到所有共享鎖消失以後,pending鎖狀態的資料庫檔案將在獲取排他鎖之後進入exclusive狀態。
5). exclusive:
在執行寫操作之前,該程序必須先獲取該資料庫的排他鎖。然而一旦擁有了排他鎖,任何其它鎖型別都不能與之共存。因此,為了最大化併發效率,sqlite將會最小化排他鎖被持有的時間總量。
最後需要說明的是,和其它關係型資料庫相比,如mysql、oracle等,sqlite資料庫中所有的資料都儲存在同一檔案中,與此同時,它卻僅僅提供了粗粒度的檔案鎖,因此,sqlite在併發性和伸縮性等方面和其它關係型資料庫還是無法比擬的。由此可見,sqlite有其自身的適用場景,就如在本系列開篇中所說,它和其它關係型資料庫之間的互換性還是非常有限的。
三、回滾日誌:
當乙個程序要改變資料庫檔案的時候,它首先將未改變之前的內容記錄到回滾日誌檔案中。如果sqlite中的某一事務正在試圖修改多個資料庫中的資料,那麼此時每乙個資料庫都將生成乙個屬於自己的回滾日誌檔案,用於分別記錄屬於自己的資料改變,與此同時還要生成乙個用於協調多個資料庫操作的主資料庫日誌檔案,在主資料庫日誌檔案中將包含各個資料庫回滾日誌檔案的檔名,在每個回滾日誌檔案中也同樣包含了主資料庫日誌檔案的檔名資訊。然而對於無需主資料庫日誌檔案的回滾日誌檔案,其中也會保留主資料庫日誌檔案的資訊,只是此時該資訊的值為空。
我們可以將回滾日誌視為"hot"日誌檔案,因為它的存在就是為了恢復資料庫的一致性狀態。當某一程序正在更新資料庫時,應用程式或os突然崩潰,這樣更新操作就不能順利完成。因此我們可以說"hot"日誌只有在異常條件下才會生成,如果一切都非常順利的話,該檔案將永遠不會存在。
四、資料寫入:
sqlite3在實現上確實針對鎖和併發控制做出了一些精巧的變化,特別是對於事務這一sql語言級別的特徵。在預設情況下,sqlite3會將所有的sql操作置於antocommit模式下,這樣所有針對資料庫的修改操作都會在sql命令執行結束後被自動提交。在sqlite中,sql命令"begin transaction"用於顯式的宣告乙個事務,即其後的sql語句在執行後都不會自動提交,而是需要等到sql命令"commit"或"rollback"被執行時,才考慮提交還是回滾。由此可以推斷出,在begin命令被執行後並沒有立即獲得任何型別的鎖,而是在執行第乙個select語句時才得到乙個共享鎖,或者是在執行第乙個dml語句時才獲得乙個保留鎖。至於排它鎖,只有在資料從記憶體寫入磁碟時開始,直到事務提交或回滾之前才能持有排它鎖。
如果多個sql命令在同乙個時刻同乙個資料庫連線中被執行,autocommit將會被延遲執行,直到最後乙個命令完成。比如,如果乙個select語句正在被執行,在這個命令執行期間,需要返回所有檢索出來的行記錄,如果此時處理結果集的執行緒因為業務邏輯的需要被暫時掛起並處於等待狀態,而其它的執行緒此時或許正在該連線上對該資料庫執行insert、update或delete命令,那麼所有這些命令作出的資料修改都必須等到select檢索結束後才能被提交。
這是該系列中最後一篇關於sqlite理論與應用方面的部落格了,後面將發布兩篇關於如何利用sqlite程式設計的部落格,其中還將包含四個典型的應用**示例,望大家繼續保持關注。
SQLite學習手冊 鎖和併發控制
出處 一 概述 在sqlite中,鎖和併發控制機制都是由pager module模組負責處理的,如acid atomic,consistent,isolated,and durable 在含有資料修改的事務中,該模組將確保或者所有的資料修改全部提交,或者全部回滾。與此同時,該模組還提供了一些磁碟檔案...
SQLite學習手冊 鎖和併發控制
一 概述 在sqlite中,鎖和併發控制機制都是由pager module模組負責處理的,如acid atomic,consistent,isolated,and durable 在含有資料修改的事務中,該模組將確保或者所有的資料修改全部提交,或者全部回滾。與此同時,該模組還提供了一些磁碟檔案的記憶...
SQLite學習手冊 鎖和併發控制
一 概述 在sqlite中,鎖和併發控制機制都是由pager module模組負責處理的,如acid atomic,consistent,isolated,and durable 在含有資料修改的事務中,該模組將確保或者所有的資料修改全部提交,或者全部回滾。與此同時,該模組還提供了一些磁碟檔案的記憶...