sqlite3 事務、調整頁面緩存、等待鎖、代碼
事務
一、事務生命周期
- 何時開始?何時結束?
在任何時候,只在一個事務下執行一個連接。
- 何時開始影響其他連接?
自動提交模式下,每發一個命令就運行一個單獨的事務;發出begin命令時,直到COMMIT或rollback,為一個事務。
二、鎖狀態
UNLOCK、PENDING、SHARED、RESERVED都可在同一時間同一數據庫的不同連接中存在。
EXCLUSIVE:排他鎖
鎖到事務結束或系統崩潰時,才會釋放。
三、讀事務
以兩次select操作為例。
- 顯示事務只鎖定一次,且能確認兩次查詢結果一致。
- 隱式事務會鎖定兩次,且無法保證兩次結果一致。
四、寫事務
1、保留狀態
準備寫入時,必須從共享鎖轉換到保留鎖。
此時的修改存儲在本地pager內的內存緩存中。
pager管理的三種頁面:
已修改頁:B-tree已改變記錄的頁。
未修改頁:B-tree讀取但並未改變的頁。
日誌頁:B-tree修改前會將其原始頁寫入日誌。
編譯選項cache_size可配置緩存。
2、待定狀態
待定鎖的作用是阻止其他連接獲取待定鎖。等待其他連接釋放其共享鎖,數據庫就可進行寫操作了。pager從待定狀態裝換到獨占狀態。
3、獨占狀態
主要工作是將修改的頁面緩存刷新至數據庫文件中。
刷新策略通過編譯指示synchronous設置。
事務提交後,pager清理日誌,清理頁緩存,從獨占鎖回到未鎖定狀態。
4、自動提交與效率
顯示事務效率和安全性更高。
調整頁面緩存
一、過渡到獨占狀態
sqlite3有可能由於頁面緩存滿而被迫進入獨占狀態。
對於頁面緩存滿的情況,sqlite存在軟限制。即由於緩存是已修改項和未修改頁的混合。此時,pager將試圖消除頁面緩存,將未修改頁清除。緩存滿後,再次重復以上過程。直至緩存被修改頁填滿,只能進入獨占狀態。
應盡量提供大的緩存,以提高整體並發性。
二、調整頁面緩存
可用sqlite3_analyzer工具對數據表進行分析。
三、等待鎖
對應處理無法獲取共享鎖(返回SQLITE_BUSY)的情況。
可通過註冊繁忙處理程序或調用sqlite3_busy_timeout()處理上述問題。
調用sqlite3_busy_timeout(),只是消磨時間等待。pager自動處理此過程,休眠時間到,返回SQLITE_BUSY。
sqlite3 事務、調整頁面緩存、等待鎖、代碼