相關(guān)概念
Connection 和 Statements。Connection是負責在一個事務中建立連接池,Statement包括sql語句的解析、執(zhí)行語句的資源、指向硬盤記錄的游標和參數(shù)。
每一個數(shù)據(jù)庫有一個B-Tree(B樹)對象,而B-Tree對象又持有一個pager對象。當用戶從發(fā)起一條sql語句去操作數(shù)據(jù)庫,這時Statement調(diào)用游標(Cursor),游標去B-Tree里,委托pager把disk上的數(shù)據(jù)取出放到緩沖區(qū)中。Pager的主要職責是管理內(nèi)存緩存和page、事務管理、鎖和崩潰事件。
sqlite創(chuàng)建物理文件也是懶加載,只有在數(shù)據(jù)寫入時才會創(chuàng)建文件,否則只是一個空文件,nothing in it~一個連接只會在一個事務下
連接數(shù)據(jù)庫的生命周期
- 連接數(shù)據(jù)庫
- 執(zhí)行事務
- 關(guān)閉連接
預處理查詢
- 這個步驟是SQLite執(zhí)行所有sql命令的方式,預處理把分析器、分詞器、代碼生成器把Statement編譯成VDBE字節(jié)碼,編譯器會生成sqlite3_stmt句柄。
- 由sqlite3_prepare去編譯字節(jié)碼,sqlite3_step啟動虛擬機去遍歷物理文件
事務
- SQLite里鎖的狀態(tài)包含以下幾個:
UNLOCKED 未加鎖
SHARED 共享
RESERVED 保留
PENDING 未決
EXCLUSIVE 排他
SQLite使用的是粗放型的鎖機制。首先讀數(shù)據(jù)只會用到共享鎖(SHARED),多個連接可以共享并保持共享鎖。當這時有一個寫操作進來時,會獲取保留鎖(RESERVED),一個連接僅且只有一個保留鎖,這時候數(shù)據(jù)庫可接受其他新的讀操作再獲取共享鎖,但不影響已經(jīng)獲取共享鎖的讀操作。然后等到所有讀操作完成之后,保留鎖會提升到未決鎖(PENDING),到這個階段數(shù)據(jù)庫會阻止所有新獲取共享鎖的操作,但已有共享鎖的操作還能繼續(xù)進行,等到所有共享鎖完成操作之后,未決鎖會提升到排他鎖(EXCLUSIVED),這時才是真正寫入數(shù)據(jù)庫文件。
- SQLite可以高效的處理在同一時刻的多個讀連接和一個寫連接
- 為什么要用EXCUSIVE鎖?
主要處于并發(fā)性的考慮,由于SQLite只有庫級的EXCUSIVE鎖,如果當開始進行寫操作時就是用這個鎖,然后再進行實際的數(shù)據(jù)更新,那么并發(fā)性的性能會大大降低。所以SQLite當獲取到RESERVED鎖時,其他進程可以同時進行讀操作,直到寫入數(shù)據(jù)庫一刻才鎖庫。
以下是sqlite狀態(tài)鎖的流程圖:
