成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

SQLite教程(十二):鎖和并發(fā)控制詳解

瀏覽:599日期:2023-04-05 14:55:59

一、概述:

    在SQLite中,鎖和并發(fā)控制機制都是由pager_module模塊負責處理的,如ACID(Atomic, Consistent, Isolated, and Durable)。在含有數(shù)據(jù)修改的事務(wù)中,該模塊將確保或者所有的數(shù)據(jù)修改全部提交,或者全部回滾。與此同時,該模塊還提供了一些磁盤文件的內(nèi)存Cache功能。
    事實上,pager_module模塊并不關(guān)心數(shù)據(jù)庫存儲的細節(jié),如B-Tree、編碼方式、索引等,它只是將其視為由統(tǒng)一大小(通常為1024字節(jié))的數(shù)據(jù)塊構(gòu)成的單一文件,其中每個塊被稱為一個頁(page)。在該模塊中頁的起始編號為1,即第一個頁的索引值是1,其后的頁編號以此類推。
   
二、文件鎖:

    在SQLite的當前版本中,主要提供了以下五種方式的文件鎖狀態(tài)。
    1). UNLOCKED:
    文件沒有持有任何鎖,即當前數(shù)據(jù)庫不存在任何讀或?qū)懙牟僮鳌F渌倪M程可以在該數(shù)據(jù)庫上執(zhí)行任意的讀寫操作。此狀態(tài)為缺省狀態(tài)。
    2). SHARED:
    在此狀態(tài)下,該數(shù)據(jù)庫可以被讀取但是不能被寫入。在同一時刻可以有任意數(shù)量的進程在同一個數(shù)據(jù)庫上持有共享鎖,因此讀操作是并發(fā)的。換句話說,只要有一個或多個共享鎖處于活動狀態(tài),就不再允許有數(shù)據(jù)庫文件寫入的操作存在。
    3). RESERVED:
    假如某個進程在將來的某一時刻打算在當前的數(shù)據(jù)庫中執(zhí)行寫操作,然而此時只是從數(shù)據(jù)庫中讀取數(shù)據(jù),那么我們就可以簡單的理解為數(shù)據(jù)庫文件此時已經(jīng)擁有了保留鎖。當保留鎖處于活動狀態(tài)時,該數(shù)據(jù)庫只能有一個或多個共享鎖存在,即同一數(shù)據(jù)庫的同一時刻只能存在一個保留鎖和多個共享鎖。在Oracle中此類鎖被稱之為預(yù)寫鎖,不同的是Oracle中鎖的粒度可以細化到表甚至到行,因此該種鎖在Oracle中對并發(fā)的影響程序不像SQLite中這樣大。
    4). PENDING:
    PENDING鎖的意思是說,某個進程正打算在該數(shù)據(jù)庫上執(zhí)行寫操作,然而此時該數(shù)據(jù)庫中卻存在很多共享鎖(讀操作),那么該寫操作就必須處于等待狀態(tài),即等待所有共享鎖消失為止,與此同時,新的讀操作將不再被允許,以防止寫鎖饑餓的現(xiàn)象發(fā)生。在此等待期間,該數(shù)據(jù)庫文件的鎖狀態(tài)為PENDING,在等到所有共享鎖消失以后,PENDING鎖狀態(tài)的數(shù)據(jù)庫文件將在獲取排他鎖之后進入EXCLUSIVE狀態(tài)。
    5). EXCLUSIVE:
    在執(zhí)行寫操作之前,該進程必須先獲取該數(shù)據(jù)庫的排他鎖。然而一旦擁有了排他鎖,任何其它鎖類型都不能與之共存。因此,為了最大化并發(fā)效率,SQLite將會最小化排他鎖被持有的時間總量。
   
    最后需要說明的是,和其它關(guān)系型數(shù)據(jù)庫相比,如MySQL、Oracle等,SQLite數(shù)據(jù)庫中所有的數(shù)據(jù)都存儲在同一文件中,與此同時,它卻僅僅提供了粗粒度的文件鎖,因此,SQLite在并發(fā)性和伸縮性等方面和其它關(guān)系型數(shù)據(jù)庫還是無法比擬的。由此可見,SQLite有其自身的適用場景,就如在本系列開篇中所說,它和其它關(guān)系型數(shù)據(jù)庫之間的互換性還是非常有限的。

三、回滾日志:

    當一個進程要改變數(shù)據(jù)庫文件的時候,它首先將未改變之前的內(nèi)容記錄到回滾日志文件中。如果SQLite中的某一事務(wù)正在試圖修改多個數(shù)據(jù)庫中的數(shù)據(jù),那么此時每一個數(shù)據(jù)庫都將生成一個屬于自己的回滾日志文件,用于分別記錄屬于自己的數(shù)據(jù)改變,與此同時還要生成一個用于協(xié)調(diào)多個數(shù)據(jù)庫操作的主數(shù)據(jù)庫日志文件,在主數(shù)據(jù)庫日志文件中將包含各個數(shù)據(jù)庫回滾日志文件的文件名,在每個回滾日志文件中也同樣包含了主數(shù)據(jù)庫日志文件的文件名信息。然而對于無需主數(shù)據(jù)庫日志文件的回滾日志文件,其中也會保留主數(shù)據(jù)庫日志文件的信息,只是此時該信息的值為空。
    我們可以將回滾日志視為"HOT"日志文件,因為它的存在就是為了恢復(fù)數(shù)據(jù)庫的一致性狀態(tài)。當某一進程正在更新數(shù)據(jù)庫時,應(yīng)用程序或OS突然崩潰,這樣更新操作就不能順利完成。因此我們可以說"HOT"日志只有在異常條件下才會生成,如果一切都非常順利的話,該文件將永遠不會存在。

四、數(shù)據(jù)寫入:

    如果某一進程要想在數(shù)據(jù)庫上執(zhí)行寫操作,那么必須先獲取共享鎖,在共享鎖獲取之后再獲取保留鎖。因為保留鎖則預(yù)示著在將來某一時刻該進程將會執(zhí)行寫操作,所以在同一時刻只有一個進程可以持有一把保留鎖,但是其它進程可以繼續(xù)持有共享鎖以完成數(shù)據(jù)讀取的操作。如果要執(zhí)行寫操作的進程不能獲取保留鎖,那么這將說明另一進程已經(jīng)獲取了保留鎖。在此種情況下,寫操作將失敗,并立即返回SQLITE_BUSY錯誤。在成功獲取保留鎖之后,該寫進程將創(chuàng)建回滾日志。
    在對任何數(shù)據(jù)作出改變之前,寫進程會將待修改頁中的原有內(nèi)容先行寫入回滾日志文件中,然而,這些數(shù)據(jù)發(fā)生變化的頁起初并不會直接寫入磁盤文件,而是保留在內(nèi)存中,這樣其它進程就可以繼續(xù)讀取該數(shù)據(jù)庫中的數(shù)據(jù)了。
    或者是因為內(nèi)存中的cache已滿,或者是應(yīng)用程序已經(jīng)提交了事務(wù),最終,寫進程將數(shù)據(jù)更新到數(shù)據(jù)庫文件中。然而在此之前,寫進程必須確保沒有其它的進程正在讀取數(shù)據(jù)庫,同時回滾日志中的數(shù)據(jù)確實被物理的寫入到磁盤文件中,其步驟如下:
    1). 確保所有的回滾日志數(shù)據(jù)被物理的寫入磁盤文件,以便在出現(xiàn)系統(tǒng)崩潰時可以將數(shù)據(jù)庫恢復(fù)到一致的狀態(tài)。
    2). 獲取PENDING鎖,再獲取排他鎖,如果此時其它的進程仍然持有共享鎖,寫入線程將不得不被掛起并等待直到那些共享鎖消失之后,才能進而得到排他鎖。
    3). 將內(nèi)存中持有的修改頁寫出到原有的磁盤文件中。
    如果寫入到數(shù)據(jù)庫文件的原因是因為cache已滿,那么寫入進程將不會立刻提交,而是繼續(xù)對其它頁進行修改。但是在接下來的修改被寫入到數(shù)據(jù)庫文件之前,回滾日志必須被再一次寫到磁盤中。還要注意的是,寫入進程獲取到的排他鎖必須被一直持有,直到所有的改變被提交時為止。這也意味著,從數(shù)據(jù)第一次被刷新到磁盤文件開始,直到事務(wù)被提交之前,其它的進程不能訪問該數(shù)據(jù)庫。
    當寫入進程準備提交時,將遵循以下步驟:
    4). 獲取排他鎖,同時確保所有內(nèi)存中的變化數(shù)據(jù)都被寫入到磁盤文件中。
    5). 將所有數(shù)據(jù)庫文件的變化數(shù)據(jù)物理的寫入到磁盤中。
    6). 刪除日志文件。如果在刪除之前出現(xiàn)系統(tǒng)故障,進程在下一次打開該數(shù)據(jù)庫時仍將基于該HOT日志進行恢復(fù)操作。因此只有在成功刪除日志文件之后,我們才可以認為該事務(wù)成功完成。
    7). 從數(shù)據(jù)庫文件中刪除所有的排他鎖和PENDING鎖。
    一旦PENDING鎖被釋放,其它的進程就可以開始再次讀取數(shù)據(jù)庫了。
    如果一個事務(wù)中包含多個數(shù)據(jù)庫的修改,那么它的提交邏輯將更為復(fù)雜,見如下步驟:
    4). 確保每個數(shù)據(jù)庫文件都已經(jīng)持有了排他鎖和一個有效的日志文件。
    5). 創(chuàng)建主數(shù)據(jù)庫日志文件,同時將每個數(shù)據(jù)庫的回滾日志文件的文件名寫入到該主數(shù)據(jù)庫日志文件中。
    6). 再將主數(shù)據(jù)庫日志文件的文件名分別寫入到每個數(shù)據(jù)庫回滾日志文件的指定位置中。
    7). 將所有的數(shù)據(jù)庫變化持久化到數(shù)據(jù)庫磁盤文件中。
    8). 刪除主日志文件,如果在刪除之前出現(xiàn)系統(tǒng)故障,進程在下一次打開該數(shù)據(jù)庫時仍將基于該HOT日志進行恢復(fù)操作。因此只有在成功刪除主日志文件之后,我們才可以認為該事務(wù)成功完成。
    9). 刪除每個數(shù)據(jù)庫各自的日志文件。
    10).從所有數(shù)據(jù)庫中刪除掉排他鎖和PENDING鎖。
   
    最后需要說明的是,在SQLite2中,如果多個進程正在從數(shù)據(jù)庫中讀取數(shù)據(jù),也就是說該數(shù)據(jù)庫始終都有讀操作發(fā)生,即在每一時刻該數(shù)據(jù)庫都持有至少一把共享鎖,這樣將會導(dǎo)致沒有任何進程可以執(zhí)行寫操作,因為在數(shù)據(jù)庫持有讀鎖的時候是無法獲取寫鎖的,我們將這種情形稱為"寫?zhàn)囸I"。在SQLite3中,通過使用PENDING鎖則有效的避免了"寫?zhàn)囸I"情形的發(fā)生。當某一進程持有PENDING鎖時,已經(jīng)存在的讀操作可以繼續(xù)進行,直到其正常結(jié)束,但是新的讀操作將不會再被SQLite接受,所以在已有的讀操作全部結(jié)束后,持有PENDING鎖的進程就可以被激活并試圖進一步獲取排他鎖以完成數(shù)據(jù)的修改操作。
   
五、SQL級別的事務(wù)控制:

    SQLite3在實現(xiàn)上確實針對鎖和并發(fā)控制做出了一些精巧的變化,特別是對于事務(wù)這一SQL語言級別的特征。在缺省情況下,SQLite3會將所有的SQL操作置于antocommit模式下,這樣所有針對數(shù)據(jù)庫的修改操作都會在SQL命令執(zhí)行結(jié)束后被自動提交。在SQLite中,SQL命令"BEGIN TRANSACTION"用于顯式的聲明一個事務(wù),即其后的SQL語句在執(zhí)行后都不會自動提交,而是需要等到SQL命令"COMMIT"或"ROLLBACK"被執(zhí)行時,才考慮提交還是回滾。由此可以推斷出,在BEGIN命令被執(zhí)行后并沒有立即獲得任何類型的鎖,而是在執(zhí)行第一個SELECT語句時才得到一個共享鎖,或者是在執(zhí)行第一個DML語句時才獲得一個保留鎖。至于排它鎖,只有在數(shù)據(jù)從內(nèi)存寫入磁盤時開始,直到事務(wù)提交或回滾之前才能持有排它鎖。
    如果多個SQL命令在同一個時刻同一個數(shù)據(jù)庫連接中被執(zhí)行,autocommit將會被延遲執(zhí)行,直到最后一個命令完成。比如,如果一個SELECT語句正在被執(zhí)行,在這個命令執(zhí)行期間,需要返回所有檢索出來的行記錄,如果此時處理結(jié)果集的線程因為業(yè)務(wù)邏輯的需要被暫時掛起并處于等待狀態(tài),而其它的線程此時或許正在該連接上對該數(shù)據(jù)庫執(zhí)行INSERT、UPDATE或DELETE命令,那么所有這些命令作出的數(shù)據(jù)修改都必須等到SELECT檢索結(jié)束后才能被提交。

    這是該系列中最后一篇關(guān)于SQLite理論與應(yīng)用方面的博客了,后面將發(fā)布兩篇關(guān)于如何利用SQLite編程的博客,其中還將包含四個典型的應(yīng)用代碼示例,望大家繼續(xù)保持關(guān)注。

標簽: SQLite
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
一本久道久久综合狠狠爱| 久久综合狠狠综合| 欧美精品九九99久久| 亚洲国产综合色| 好吊色欧美一区二区三区四区| 日韩欧美中文字幕制服| 精品一区二区三区影院在线午夜| 久久精品人人| 亚洲一二三四区| 亚洲深夜av| 亚洲人成网站影音先锋播放| 91香蕉视频污| 久久久亚洲精华液精华液精华液| 国产999精品久久久久久| 3d动漫精品啪啪1区2区免费| 午夜国产精品影院在线观看| 美女主播一区| 亚洲国产精品人人做人人爽| 国产精品欧美久久| 亚洲国产精品自拍| 久久精品日韩欧美| 偷窥少妇高潮呻吟av久久免费| 国产精品免费一区二区三区观看| 亚洲美女在线一区| 国产麻豆日韩| 亚洲中国最大av网站| 男女av一区三区二区色多| 亚洲成人免费视频| 久久av二区| 免费一级欧美片在线观看| 在线视频国内自拍亚洲视频| 日韩一区欧美二区| 色呦呦日韩精品| 激情综合网最新| 日韩精品中文字幕一区| 99久久精品国产观看| 国产精品沙发午睡系列990531| 激情文学一区| 亚洲愉拍自拍另类高清精品| 国产精品制服诱惑| 午夜久久久久久| 欧美三级乱人伦电影| 国产福利精品一区| 久久亚洲精品国产精品紫薇 | 黄页网站大全一区二区| 欧美伦理影视网| 成人午夜电影网站| 国产欧美日韩另类视频免费观看| 亚洲午夜黄色| 亚洲主播在线观看| 欧美综合一区二区| 欧美成人一区二区三区在线观看| 91在线视频在线| 日韩一区中文字幕| 国产日韩一区欧美| 日韩精品国产精品| 7777精品伊人久久久大香线蕉经典版下载 | 国产精品vip| 亚洲男人的天堂在线aⅴ视频| 午夜综合激情| 国产曰批免费观看久久久| 欧美不卡一区二区| 黄色在线一区| 天天影视色香欲综合网老头| 欧美日本韩国一区| 午夜久久福利| 亚洲国产美女搞黄色| 欧美裸体一区二区三区| 92国产精品观看| 亚洲亚洲精品在线观看| 欧美人牲a欧美精品| 97se亚洲国产综合自在线不卡| 自拍偷拍欧美精品| 在线亚洲高清视频| 99精品欧美一区二区蜜桃免费| 一区二区理论电影在线观看| 欧美巨大另类极品videosbest| 欧美日产一区二区三区在线观看| 亚瑟在线精品视频| 欧美一级午夜免费电影| 国产精品二区二区三区| 天堂va蜜桃一区二区三区| 日韩欧美一区二区视频| 尤物在线精品| 极品少妇xxxx精品少妇偷拍 | 午夜精品久久久久| 欧美成人a∨高清免费观看| 亚洲国产99| 国产真实乱子伦精品视频| 亚洲国产高清不卡| 欧美性大战xxxxx久久久| 欧美日本高清| 九一久久久久久| 中文字幕一区二区三区不卡| 欧美视频精品在线观看| 欧美天天在线| 久久99精品久久久久| 国产精品色在线观看| 欧美日韩国产bt| 伊甸园精品99久久久久久| 国内精品伊人久久久久av一坑 | 国产精品久久久久婷婷二区次| 一本一本大道香蕉久在线精品| 91猫先生在线| 日韩av网站在线观看| 亚洲国产成人一区二区三区| 欧美日本精品一区二区三区| 亚洲第一在线| 福利一区福利二区| 五月婷婷激情综合| 国产视频在线观看一区二区三区| 欧美午夜寂寞影院| 亚洲美女黄色| 成人国产精品免费观看动漫| 日韩精品电影一区亚洲| 久久精品视频免费观看| 欧美系列亚洲系列| 一本一本久久a久久精品综合妖精| 成人久久久精品乱码一区二区三区| 亚洲一区二区偷拍精品| 国产视频一区不卡| 在线电影一区二区三区| 久久国产欧美| 欧美久久视频| 风间由美一区二区av101| 日韩福利电影在线观看| 亚洲乱码国产乱码精品精98午夜 | 亚洲天天做日日做天天谢日日欢| 日韩一区二区麻豆国产| 一本一道久久a久久精品综合蜜臀| 激情久久久久久| caoporm超碰国产精品| 久久国产精品99精品国产| 亚洲最新在线观看| 国产精品视频一二三区| 日韩美女在线视频| 欧美日韩欧美一区二区| 久久亚洲影院| 亚洲一区激情| 亚洲国产电影| 欧美日韩精品一区| 成人毛片在线观看| 久草中文综合在线| 日本欧美久久久久免费播放网| 亚洲天堂福利av| 国产精品水嫩水嫩| 久久综合久久鬼色中文字| 91精品国产欧美一区二区| 欧美体内she精高潮| 久久国产精品免费一区| 亚洲人人精品| 亚洲私拍自拍| 欧美日韩hd| eeuss国产一区二区三区| 国产精品一区二区91| 欧美aⅴ一区二区三区视频| 亚洲电影一级片| 一个色在线综合| 亚洲免费观看高清完整| 亚洲视频图片小说| 亚洲色图欧洲色图| 中文字幕在线一区| 中文字幕av免费专区久久| 久久久久久久久岛国免费| 欧美精品一区二区三区蜜臀| 欧美不卡一区二区三区| 欧美α欧美αv大片| 欧美xxxxxxxx| 日韩免费在线观看| 日韩一区二区三区视频在线观看 | 91精品久久久久久久99蜜桃| 精品视频在线免费看| 欧美三区在线视频| 欧美日韩成人综合| 欧美日本在线观看| 欧美精品一卡二卡| 欧美区一区二区三区| 91麻豆精品国产91久久久久久| 91精品国产全国免费观看| 欧美一区二区女人| 日韩欧美一级二级三级久久久| 日韩欧美国产一区二区在线播放| 日韩精品一区二区三区在线观看| 日韩欧美亚洲一区二区| 日韩精品一区二区三区swag| 日韩欧美一二三区| 久久久久久亚洲综合| 中文字幕二三区不卡| 国产精品久久久久桃色tv| 国产精品另类一区| 亚洲欧美一区二区三区孕妇| 最近日韩中文字幕| 亚洲香肠在线观看| 日韩国产欧美在线播放| 久久国产综合精品| 国产乱码精品一区二区三区忘忧草| 高清在线成人网| 91美女在线看| 欧美日韩三区| 亚洲黄色影片|