之前講的都是概念,關於實際怎么防止調度讀到或者寫到自己不該寫的東西我們其實一!點!都!沒!講!啦啦啦
實際中實現isolation這個性質的機制有兩種,一種被稱為TWO_PHASE LOCKING 還有一個被稱為snapshot isolation,前面那個字面就很好理解,二步鎖定,后面那個直接翻譯被稱為快照隔離。下面我們講的是鎖定。
鎖定分為兩種:
shared,即分享鎖定,這個被分享鎖定所鎖定的數據可以被其他的調度套上分享鎖定。這個鎖定的擁有者對於鎖定數據的操作權限僅限於讀取數據。
exclusive, 即排外鎖定,被這種鎖鎖定的數據不能被其他的任何調度鎖定,被鎖定的數據可以被持有鎖定的調度讀和寫。
在這里需要介紹一個新的概念叫做concurrency control manager.這個系統負責控制數據庫里所有的鎖定需求。
鎖的兼容定義見上。
我們定義LOCK-S(Q)為用share模式鎖定數據Q,LOCK-X(Q)為用excluded模式鎖定數據Q,UNLOCK(Q)來取消鎖定Q。
下面進行對於鎖定的兩種使用方式的討論。
理解上圖以后我們發現,display(A+B)顯示出的結果不是正確的,因為T1過早的解鎖了B數據,而它本身的活動還沒有完結 ,而事實上我們也很明白這個結果必然是錯的,因為T1的剩下部分中有寫的部分,這樣的調度並不屬於一個serializable的調度。
所以事實上這個情況屬於T1過早的解開了鎖,導致的數據不連續。
而當我們這么寫的時候,就不需要擔心不連續了,但是很明顯的,這個調度並跑不起來,原因是顯而易見的。
而這種相互卡死的情況被稱為鎖死,當遇到鎖死的時候,必然伴隨着回滾,而回滾同時也會將原來鎖死的數據解鎖。
而在設計模式的時候我們就遇到了這個問題,我們到底是要鎖死還是要數據不連續——很明顯前者好一點,因為可以通過數據回滾來解決,而數據不連續導致的外部輸出是很難解決的。
接下來給大家帶來一個定義:
很好理解的概念吧(233
對於一個調度,如果它是符合上述封鎖協議規定的,那么我們稱它為合法調度,我們稱一個封鎖協議保證可串行性,如果在它之下的所有合法調度都是可串行化的話,這個可以用檢查內部的關系圖有無環來確定。
接下來介紹餓死的概念:
餓死,很明顯,如果說在一個要求lock-x的調度前面跟着若干個要求lock-s的調度,這個lock-x的調度將被無限延期,所以說處理調度的法則為:
1.要求的數據沒有被要求不兼容的鎖鎖住
2.前面沒有任何比它要求更早的鎖。
簡單的說,就是按遞交順序排序。