sql相同顺序法和一次封锁法_数据库:事务处理
事務基本概念
事務
是一系列的數(shù)據(jù)庫操作,是數(shù)據(jù)庫應用程序的基本邏輯單元
所謂事務是用戶自定義的一個數(shù)據(jù)庫操作序列,這些操作要么全做,要么不做,是一個不可分割的工作單位。
例如:在關系型數(shù)據(jù)庫中,一個事務可以是一條sql,一組sql或整個程序
事務和程序的區(qū)別:一般來說,一個程序中包含很多事務
事務的定義
事務的開始與結束可以由用戶顯式控制,若用戶沒有顯式控制,則有數(shù)據(jù)庫管理系統(tǒng)默認劃分事務
1、begin transaction;
事務的開始,以commit或rollback結束。
2、commit;
即提交事務的所有操作:將事務中所有對數(shù)據(jù)庫的更新寫回到磁盤上的物理數(shù)據(jù)庫中,事務正常結束。
3、rollback;
回滾,即當事務運行過程中發(fā)生了某種故障,不在繼續(xù)執(zhí)行時,系統(tǒng)將事務中對數(shù)據(jù)庫所有已完成的操作全部撤銷,回滾到事務開始時的狀態(tài)。
事務的特點
原子性
一致性
隔離性
持續(xù)性【永久性】
事務處理技術
數(shù)據(jù)庫恢復
數(shù)據(jù)恢復的常用技術:數(shù)據(jù)轉儲、登記日志文件
日志文件:
用來記錄事務對數(shù)據(jù)庫的更新操作的文件
作用:在數(shù)據(jù)庫恢復中起到重要作用,并協(xié)助后備副本進行介質故障恢復
主要包含:事務標識、操作類型、操作對象、更新前數(shù)據(jù)的舊值、更新后數(shù)據(jù)的新值
數(shù)據(jù)故障
1、事務內部故障
是非預期的,不能由應用程序處理
2、系統(tǒng)故障【軟故障】
指造成系統(tǒng)停止運轉的任何事件,使得系統(tǒng)要重啟
3、介質故障【硬故障】
4、計算機病毒
2、采用什么機制來保證數(shù)據(jù)庫并發(fā)操作的正確性?
并發(fā)控制
單處理機系統(tǒng)中,事務的并行執(zhí)行實際上是這些并行事務的并行操作輪流交叉運行
并發(fā)操作帶來的數(shù)據(jù)不一致有三種情況:
1、丟失修改
寫-寫
兩個事務T1和T2讀入同一數(shù)據(jù)并修改,T2提交的結果破壞了T1提交的結果,導致T1的修改被丟失。
解決辦法:
一種辦法是是鎖,即基于鎖的并發(fā)控制,比如2PL,這種方式開銷比較高,而且無法避免死鎖。
樂觀并發(fā)控制(OCC)是一種用來解決寫-寫沖突的無鎖并發(fā)控制,認為事務間爭用沒有那么多,所以先進行修改,在提交事務前,檢查一下事務開始后,有沒有新提交改變,如果沒有就提交,如果有就放棄并重試。樂觀并發(fā)控制類似自選鎖。樂觀并發(fā)控制適用于低數(shù)據(jù)爭用,寫沖突比較少的環(huán)境。
多版本并發(fā)控制可以結合基于鎖的并發(fā)控制來解決寫-寫沖突,即MVCC+2PL,也可以結合樂觀并發(fā)控制來解決寫-寫沖突。
2、不可重復讀
讀-寫
事務T1讀取數(shù)據(jù)后,事務T2執(zhí)行更新操作,使T1無法再現(xiàn)前一次讀取結果。
3、讀“ 臟 ”數(shù)據(jù) 【污讀】
讀-寫
事務 T1修改某一數(shù)據(jù),并將其寫回磁盤,事務T2讀取同一數(shù)據(jù)后, T1由于某種原因被撤消,這時 T1已修改過的數(shù)據(jù)恢復原值,
T2讀到的數(shù)據(jù)就與數(shù)據(jù)庫中的數(shù)據(jù)不一致,則T2讀到的數(shù)據(jù)就為"臟"數(shù)據(jù),即不正確的數(shù)據(jù)。(讀取到未提交數(shù)據(jù))
解決辦法:
多版本并發(fā)控制(MVCC)是一種用來解決讀-寫沖突的無鎖并發(fā)控制,也就是系統(tǒng)為每個事務分配單向增長的時間戳,為每個修改保存一個版本,版本與事務時間戳關聯(lián),讀操作只讀該事務開始前的數(shù)據(jù)庫的快照。 這樣在讀操作不用阻塞寫操作,寫操作不用阻塞讀操作的同時,避免了臟讀和不可重復讀。
并發(fā)控制的解決辦法
并發(fā)控制的主要技術有封鎖(locking)、時間戳(timestamp)、樂觀控制法(optimistic sheduler)和多版本并發(fā)控制(multi-version concurrency control,MVCC)等,各個技術之間是存在交叉配合使用的。商用的DBMS一般都采用封鎖方法。
悲觀并發(fā)控制:假定會發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作。
樂觀并發(fā)控制:假設不會發(fā)生并發(fā)沖突,只在提交操作時檢查是否違反數(shù)據(jù)完整性。
封鎖
事務T在對某個數(shù)據(jù)對象(例如表、記錄等)操作之前,先向系統(tǒng)發(fā)出請求,對其加鎖。加鎖后事務T就對該數(shù)據(jù)對象有了一定的控制權,在事務T釋放它的鎖之前,其它的事務不能更新此數(shù)據(jù)對象,屬于一種悲觀控制法。
封鎖的基本類型
基本的封鎖類型有兩種:排他鎖(X鎖)和共享鎖(S鎖)。
(1)排它鎖又稱寫鎖X。若事務T對數(shù)據(jù)對象A加上X鎖,只有事務T可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到T釋放A上的鎖。這保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A。
(2)共享鎖又稱讀鎖S。若事務T對數(shù)據(jù)對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。
封鎖協(xié)議
一級封鎖協(xié)議:對應事務隔離級別中的讀未提交(Read uncommited)
事務T在修改數(shù)據(jù)R之前必須先對其加X鎖,直到事務結束才釋放。事務結束包括正常結束(COMMIT)和非正常結束(ROLLBACK)。
一級封鎖協(xié)議可防止丟失修改,并保證事務T是可恢復的,因為防止其他事務進行同時修改。
在一級封鎖協(xié)議中,如果僅僅是讀數(shù)據(jù)不對其進行修改,是不需要加鎖的。所以它不能保證可重復讀和不 讀"臟"數(shù)據(jù)。
非正常結束時,X鎖就自動釋放了!
二級封鎖協(xié)議:對應事務隔離級別中的讀已提交(Read Committed)
一級封鎖協(xié)議加上事務T在讀取數(shù)據(jù)R之前必須先對其加S鎖,讀完后即可釋放S鎖。二級封鎖協(xié)議防止了丟失修改和讀"臟"數(shù)據(jù)。
遵從二級封鎖協(xié)議時發(fā)生的“不可重復讀”的過程
三級封鎖協(xié)議:對應事務隔離級別中的可重復讀(Repeatable Read)
一級封鎖協(xié)議加上事務T在讀取數(shù)據(jù)R之前必須先對其加S鎖,直到事務結束才釋放。三級封鎖協(xié)議除防止了丟失修改和不讀'臟'數(shù)據(jù)外,還進一步防止了不可重復讀。
封鎖中的死鎖與活鎖
活鎖
存在現(xiàn)象:如果事務T1封鎖了數(shù)據(jù)R,事務T2又請求封鎖數(shù)據(jù)R,于是T2等待。事務T3也請求封鎖R,當事務T1釋放了數(shù)據(jù)R上的封鎖之后系統(tǒng)首先批準了事務T3的封鎖請求,T2仍然等待。然后T4又申請封鎖R,當T3釋放了R的封鎖之后系統(tǒng)又批準了T4的封鎖請求。T2有可能一直等待下去,這就是活鎖。
解決辦法:避免活鎖的方法就是先來先服務的策略。當多個事務請求對同一數(shù)據(jù)對象封鎖時,封鎖子系統(tǒng)按照請求的先后對事務排隊。數(shù)據(jù)對象上的鎖一旦釋放就批準申請隊列中的第一個事務獲得鎖。
死鎖
存在現(xiàn)象:如果事務T1封鎖了數(shù)據(jù)R1,事務T2封鎖了數(shù)據(jù)R2,然后T1又請求封鎖數(shù)據(jù)R2,因為T2已經(jīng)封鎖了數(shù)據(jù)R2,于是T1等待T2釋放R2上的鎖。接著T2又申請封鎖R1,因為因為T1已經(jīng)封鎖了數(shù)據(jù)R1,T2也只能等待T1釋放R1上的鎖。這樣就出現(xiàn)了T1在等待T2,T2也在等待T1的局面,T1和T2兩個事務永遠不能結束,形成死鎖。
解決辦法:
1) 死鎖的預防:
①一次封鎖法
一次封鎖法要求事務必須一次將所有要使用的數(shù)據(jù)全部加鎖,否則不能繼續(xù)執(zhí)行。例如上圖中的事務T1將數(shù)據(jù)R1和R2一次加鎖,T1就能執(zhí)行下去,而T2等待。T1執(zhí)行完成之后釋放R1,R2上的鎖,T2繼續(xù)執(zhí)行。這樣就不會產生死鎖。
一次封鎖法雖然能防止死鎖的發(fā)生,但是缺點卻很明顯。一次性將以后要用到的數(shù)據(jù)加鎖,勢必擴大了封鎖的范圍 ,從而降低了系統(tǒng)的并發(fā)度。
②順序封鎖法
順序封鎖法是預先對數(shù)據(jù)對象規(guī)定一個封鎖順序,所有的事務都按照這個順序實行封鎖。
順序封鎖法雖然可以有效避免死鎖,但是問題也很明顯。第一,數(shù)據(jù)庫系統(tǒng)封鎖的數(shù)據(jù)對象極多,并且隨著數(shù)據(jù)的插入、刪除等操作不斷變化,要維護這樣的資源的封鎖順序非常困難,成本很高。第二,事務的封鎖請求可以隨著事務的執(zhí)行動態(tài)的確定,因此很難按照規(guī)定的順序實行封鎖。
可見,預防死鎖的產生并不是很適合數(shù)據(jù)庫的特點,所以在解決死鎖的問題上普遍采用的是診斷并且解除死鎖。
2) 死鎖的診斷與解除:
①超時法
如果一個事務的等待時間超過了默認的時間,就認為是產生了死鎖。
②等待圖法
一旦檢測到系統(tǒng)中存在死鎖就要設法解除。通常的解決方法是選擇一個處理死鎖代價最小的事務,將其撤銷,釋放此事務持有的所有的鎖,恢復其所執(zhí)行的數(shù)據(jù)修改操作,使得其他事務得以運行下去。
兩段鎖協(xié)議2PL
所謂的二段鎖協(xié)議是指所有事務必須分兩個階段對數(shù)據(jù)進行加鎖和解鎖操作。
在對任何數(shù)據(jù)進行讀、寫操作之前,首先要申請并獲得該數(shù)據(jù)的封鎖。
在釋放一個封鎖之后,事務不在申請和獲得其他封鎖。
也就是說事務分為兩個階段。第一個階段是獲得封鎖,也稱為擴展階段。在這個階段,事務可以申請獲得任何數(shù)據(jù)項任何類型的鎖,但是不能釋放任何鎖。第二階段是釋放封鎖,也稱為收縮階段。在這個階段,事務可以釋放任何數(shù)據(jù)項上任何類型的封鎖,但是不能再申請任何鎖。
事務遵守兩段鎖協(xié)議是可串行化調度的充分條件,而不是必要條件。也就是說遵守兩段鎖協(xié)議一定是可串行化調度的,而可串行化調度的不一定是遵守兩段鎖協(xié)議的。
兩段鎖協(xié)議和一次封鎖法的異同
一次封鎖法要求事務必須將要使用的數(shù)據(jù)全部加鎖,否則不能繼續(xù)執(zhí)行。因此一次封鎖法遵守兩段鎖協(xié)議。
但是兩段鎖協(xié)議并不要求事務將要使用的數(shù)據(jù)一次全部加鎖,因此兩段鎖協(xié)議可能發(fā)生死鎖。
時間戳
給每個事務分配一個全局惟一的時間戳。時間截的值產生了一個精確的順序,事務按照該順序提交。時間戳必須有兩個特性:惟一性和單調性,惟一性保證不存在相等的時間戳值,單調性保證時間戳的值是一直增長的。
同一事務中所有的數(shù)據(jù)庫操作(讀和寫)都必須有相同的時間戳。DBMS按照時間戳順序執(zhí)行沖突的事務,因此保證了事務的可串行化。如果兩個事務沖突,通常終止其中一個,將其回滾并重新調度,賦予新的時間戳。
用時間戳實現(xiàn)并發(fā)控制,需要為數(shù)據(jù)庫中每個值附加兩個字段
讀時間戳:用于保存所有訪問該記錄的事務中的最大時間戳(最后讀取時間)
寫時間戳:用于保存將記錄改到當前值的事務的時間戳(最后修改時間)
因此時間戳增加了內存需求和數(shù)據(jù)庫的處理開銷,因為有可能導致許多事務被終止,重新調度和重新賦予時間戳,時間戳方法一般需要大量的系統(tǒng)資源.
這樣的事務在并行執(zhí)行時,用的是樂觀控制,先任由事務對數(shù)據(jù)進行修改,在寫回去的時候在判斷記錄的時間戳有沒有修改,如果沒有被修改,就寫入,否則,就生成一個新的時間戳并再次嘗試更新數(shù)據(jù)。
樂觀控制法
樂觀方法基于這樣的假設,數(shù)據(jù)庫操作的大部分都不會發(fā)生沖突,樂觀方法不要求鎖定,作為替換,事務不受限制地被執(zhí)行,直到它被提交,便用樂觀方法,每個事務經(jīng)過兩個或者三個階段,它們是讀、確認、寫。
(1)讀階段,事務讀取數(shù)據(jù)庫,執(zhí)行需要的計算,并對一個私有的數(shù)據(jù)庫值的副本進行更新,事務的所有更新操作都記錄在一個臨時更新文件中,該文件將不 ,會被剩下的其他事務訪問.
(2)確認階段,對事務進行確認以保證所做的修改不會影響數(shù)據(jù)庫的完整性和一致性,如果確認檢查是肯定的,事務進入寫階段;如果確認檢查是否定的,則事務回滾,重新啟動,所做的修改被拋棄
(3)寫階段,所做的修改被永久地寫入到數(shù)據(jù)庫中,樂觀方法對于大多數(shù)只有較少更新事務的查詢數(shù)據(jù)庫系統(tǒng)來說是可以接受的,
多版本并發(fā)控制
MVCC (Multiversion Concurrency Control),即多版本并發(fā)控制技術,是一種并發(fā)控制的方法,一般在數(shù)據(jù)庫管理系統(tǒng)中,實現(xiàn)對數(shù)據(jù)庫的并發(fā)訪問。在MVCC中,每個事務操作的是數(shù)據(jù)的一個快照,寫操作造成的變化在寫操作完成之前(或者數(shù)據(jù)庫事務提交之前)對于其他的事務來說是不可見的。
當一個 MVCC 數(shù)據(jù)庫需要更一個一條數(shù)據(jù)記錄的時候,它不會直接用新數(shù)據(jù)覆蓋舊數(shù)據(jù),而是將舊數(shù)據(jù)標記為過時(obsolete)并在別處增加新版本的數(shù)據(jù)。這樣就會有存儲多個版本的數(shù)據(jù),但是只有一個是最新的。這種方式允許事務讀取在他讀之前已經(jīng)存在的數(shù)據(jù),即使這些在讀的過程中半路被別人修改、刪除了,也對先前正在讀的用戶沒有影響。這種多版本的方式避免了填充刪除操作在內存和磁盤存儲結構造成的空洞的開銷,但是需要系統(tǒng)周期性整理(sweep through)以真實刪除老的、過時的數(shù)據(jù)。
MVCC 并發(fā)控制下的讀事務一般使用時間戳或者事務ID去標記當前讀的數(shù)據(jù)庫的狀態(tài)(版本),讀取這個版本的數(shù)據(jù)。讀、寫事務相互隔離,不需要加鎖。讀寫并存的時候,寫操作會根據(jù)目前數(shù)據(jù)庫的狀態(tài),創(chuàng)建一個新版本,并發(fā)的讀則依舊訪問舊版本的數(shù)據(jù)。
一句話講,MVCC就是用 同一份數(shù)據(jù)臨時保留多版本的方式的方式,實現(xiàn)并發(fā)控制。
這里留意到 MVCC 關鍵的兩個點:
在讀寫并發(fā)的過程中如何實現(xiàn)多版本;
在讀寫并發(fā)之后,如何實現(xiàn)舊版本的刪除(畢竟很多時候只需要一份最新版的數(shù)據(jù)就夠了)
轉載
總結
以上是生活随笔為你收集整理的sql相同顺序法和一次封锁法_数据库:事务处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TPKeyboardAvoidingSc
- 下一篇: php爬取flash的交互数据库,基于P