資料庫鎖機制

2022-07-18 06:57:12 字數 4039 閱讀 6330

多使用者併發運算元據庫的時候,如果嚴格執行序列準則(serializable ),當然是最穩妥安全的做法——比如我們去車站買票,只開放乙個視窗,人人都得排隊,依次買票或退票。但是這個世界是追求效率的,於是乎,車站可能會多開幾個視窗,讓買票速度變快。隨之而來,會產生資源衝突——同乙個座位可能被賣給多個人、最後一張票可能被賣給多個人、系統顯示某個座位已售售票員以為是這個人買的其實是另乙個人買的、乙個人正在退票呢可其他視窗的售票員卻告訴大家票已經售光了回家去吧,等等。

最基本的鎖型別:

共享鎖說句廢話,讀操作select和讀鎖是兩個概念,一般情況下,讀操作可以不加鎖,也可以加讀鎖,在必要的情況下,還可以加排他鎖。這取決於想要達到的目的。

當前事務的鎖 

其他事務的行為讀讀鎖

寫寫鎖共享鎖允許

允許不許

不許排它鎖

**不許

不許不許

**備註:部分資料(某行或某錶)上了排他鎖,在有些資料庫或某些版本中,是允許其他事務做讀操作的。

避免死鎖或提高效能的鎖型別:

更新鎖,為解決死鎖,引入更新鎖。更新鎖的意思是,當前還在唯讀,並沒有使用到排他鎖,但已經預定了未來會使用排他鎖。怎麼預定的呢?就是當前獲得乙個更新鎖,相當於獲得了未來使用排他鎖的資格,類似於學位,上學前就必須獲得這個學位,未來才有資格上學。注意: 1)乙個事務只能有乙個更新鎖獲此資格,類似於一戶只能有乙個學位; 2)同一時間不能在同一資源上有兩個更新鎖,這個容易理解,即,更新鎖之間是排他的; 3)排他鎖與更新鎖是不相容的,它們不能同時加在同一子資源上。用學位來比喻的話,就是說乙個家庭的小學學位正在被使用(上了排他鎖),是不可以同時被這個家庭或其他家庭用來預定學位的(不能上更新鎖),必須等這個家庭的6年學位使用完,才能被預定(上更新鎖)或被使用(上排他鎖); 3)共享鎖和更新鎖可以同時在同乙個資源上的,即他倆相容。

鎖相容關係

共享鎖

排他鎖

更新鎖

共享鎖

相容不容

相容排他鎖

不容不容

不容更新鎖

相容不容

不容意向鎖,舉個例子,某行修改時,會加上排他鎖,同時,資料庫會默默給該錶加意向鎖,表示裡面有記錄正被鎖定。其他事務如果也想在這個表的某些行加表鎖,直接在表這一層級檢查表本身是否有意向鎖,提高效率。如果沒有意向鎖這個類似指示燈的東西存在,其他人加表鎖之前就得掃瞄全表,檢視是否有記錄正被鎖定。可以認為意向鎖就是個標記,其他事務只需要看到這個表已經有意向排他鎖存在,就直接等待。

其實上面還提及了乙個維度,即加鎖的範圍/粒度,比如

行鎖,會發生死鎖,加鎖慢,但鎖定粒度小,併發度高

頁鎖,會發生死鎖,開銷、粒度、併發度介於中間

表鎖,不會發生死鎖,開銷小,但因為鎖粒度大,併發度最低。

看乙個場景,事務a和事務b同時同一張表進行操作,前兩個動作都是先讀後寫。

步驟事務a

事務b第一步

讀 1~5   行

讀 6~10 行

第二步寫 6~10 行

寫 1~5   行

步驟     

加鎖     

可能發生的問題

第一步共享鎖

情況ok

第二步排他鎖

2 事務結束後才釋放共享鎖:死鎖

唯讀已提交(read_committed)的機制解決了髒讀。共享鎖和排他鎖解決了不可重複讀等問題,但是因為共享鎖釋放的時間點不同,卻帶來了新的問題——死鎖,解決方法是,引入更新鎖。

看看更新鎖是怎麼運作的?

更新鎖其實就是對事務先上共享鎖再上排他鎖。還是這個例子,可以看出,事務a和b如果直接在第一步就使用更新鎖,無論加在a上還是加在b上,都可以解決死鎖的問題(當然,如果還存在其他事務併發,最好是都加上更新鎖):

事務a      

事務b      

結果有更新鎖

無更新鎖

第一步無論a和b誰先開始讀(select),都可以共享資源/發出共享鎖;

無論誰先讀完,第二步都是a寫資料(insert,update,delete),b等待a。無有

第一步無論a和b誰先開始讀(select),都可以共享資源/發出共享鎖;

第二步都是b獲得寫資料(insert,update,delete)的鎖,a等待b。有有

第一步無論a和b誰先開始讀(select),先讀的那個會先使用更新鎖,允許另乙個事務讀;

第二步,還是那個先讀的事務先寫資料,另一事物等待。

各種鎖的相容關係表:

鎖模式request mode

is

s

u

ix

six

x

意向 共享鎖

intent shared lock (is)

相容相容

相容相容

相容不容

共享鎖

shared lock (s)

相容相容

相容不容

不容不容

更新鎖

update lock (u)

相容相容

不容不容

不容不容

意向 排他鎖

intent exclusive lock (ix)

相容不容

不容相容

不容不容

意向 排他 共享鎖

shared with intent exclusive lock (six)

相容不容

不容不容

不容不容

排他鎖 / 獨佔鎖

exclusive lock (x)

不容不容

不容不容

不容不容

還有計畫鎖,sch-m,sch-s:

對資料庫結構改變時用sch-m (ddl語句會加sch-m modification 鎖,比如alter table語句;該鎖不允許任何其它session會話連線該錶);

對查詢進行編譯時用架構穩定性鎖sch-s (用jdbc向資料庫傳送了一條新的sql語句"select * from table_a",資料庫要先對之進行編譯,在編譯期間,也會加sch-s stability 鎖,且此段時間其他的session可以對錶a做任何update,delete,加排他鎖等操作,但不能做dll中的alter table等操作)—— 這兩種鎖不會阻塞任何事務鎖,包括獨佔鎖。使用with(nolock)的會話也可能被正在執行的還未提交的schema change阻塞,如alter table table_a add grade varchar(10)。還有一種情況,以sql server為例,當使用者在用 with(nolock) 的時候,本意是讓執行語句不加任和鎖,相當於 read uncommitted 隔離模式;實際上,使用了with(nolock)後,資料庫依然對該錶物件生成sch-s(架構穩定性)鎖以及db型別的共享鎖,這是資料庫的預設機制。

資料庫鎖機制

這段時間由於開發專案,重新學習了資料庫的併發控制和鎖機制。資料庫就是通過鎖機制來解決併發問題的。主要就是兩種鎖,共享鎖和排他鎖 也叫獨佔鎖 在執行select語句的時候需要給操作物件 表或者一些記錄 加上共享鎖,但加鎖之前需要檢查是否有排他鎖,如果沒有,則可以加共享鎖 乙個物件上可以加n個共享鎖 否...

資料庫鎖機制

這段時間由於開發專案,重新學習了資料庫的併發控制和鎖機制。資料庫就是通過鎖機制來解決併發問題的。主要就是兩種鎖,共享鎖和排他鎖 也叫獨佔鎖 在執行select語句的時候需要給操作物件 表或者一些記錄 加上共享鎖,但加鎖之前需要檢查是否有排他鎖,如果沒有,則可以加共享鎖 乙個物件上可以加n個共享鎖 否...

資料庫鎖機制

資料庫就是通過鎖機制來解決併發問題的。主要就是兩種鎖,共享鎖和排他鎖 也叫獨佔鎖 在執行select語句的時候需要給操作物件 表或者一些記錄 加上共享鎖,但加鎖之前需要檢查是否有排他鎖,如果沒有,則可以加共享鎖 乙個物件上可以加n個共享鎖 否則不行。共享鎖通常在執行完select語句之後被釋放,當然...