sql的鎖機制,是時刻貫徹在每一次的sql事務中的,為了理解更透徹,介紹鎖之前,我們得先了解,鎖是為了干什么!!
1、資料庫例外情況
1.1 先來聊聊資料可能發生個例外狀況
1)臟讀:讀未提交,顧名思義,讀到了不該讀的東西,如:

事務B讀到了事務A回滾的資料,就是臟讀
2)不可重復讀:讀已提交,同個事務內,多次讀取同個資料,卻回傳不同結果,偏向資料更新

事務B發生了不可重復讀
3) 幻讀:同個事務內,因其他事務插入或洗掉資料,導致讀取到不同的資料量(本質和不可重復讀相似)

事務B發生了幻讀
1.2 資料庫用什么機制來處理這些例外情況的發生,四種隔離級別
1)讀未提交(Read Uncommitted):發生臟讀,基本沒有資料庫使用這個級別了
2)讀已提交(Read Committed):大多數資料庫系統的默認隔離級別,解決了臟讀問題
3)可重復讀(Repeatable Read):同一事務的多個實體在并發讀取資料時,會看到同樣的資料,解決了不可重復讀問題
4)可串行化(Serializable):這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題,簡言之,它是在每個讀的資料行上加上共享鎖,但可能導致大量的超時現象和鎖競爭
總結:四種級別越往后越影響性能,但資料越穩定,實作機制就是"鎖";

2、都有什么鎖
2.1鎖的種類:
1)共享鎖:其他事務可select,無法被update、delete、insert
2)排他鎖:其他事務不可任何操作
2.2粒度提示:
1)rowlock:行鎖,指定到行,select * from dual where id=1會默認行鎖
2)paglock:頁鎖,select * from dual會默認頁鎖,select的時候先鎖定第一頁,讀取后釋放,再鎖定第二頁,直到讀完
3)tablock:表鎖,陳述句結束解鎖
4)tabockx:表鎖,排他鎖,
5)nolock:取消默認鎖,涉及大量洗掉資料的時候可能會堵塞行程,如果需要select,可以加上nolock來過濾掉需要洗掉的資料
6)holdlock:保持共享鎖,資料庫會根據sql操作加默認鎖
7)serializable:同holdlock
8)readcommited:遵循讀已提交隔離級別
9)updlock:更新鎖,排他鎖
3、舉例子
3.1 模擬場景,多個客戶在搶一個優惠券
客戶:kxy
begin tran declare @_owner varchar(100); set @_owner = (select owner from Coupons with(updlock) where id=2); if(@_owner is null or @_owner='') begin update Coupons set owner='kxy' where id=2 waitfor delay '00:00:10' print '恭喜您,搶到了!!' end; else print '該券已經被搶了!!' commit tran
客戶:keys
begin tran declare @_owner varchar(100); set @_owner = (select owner from Coupons with(updlock) where id=2); if(@_owner is null or @_owner='') begin update Coupons set owner='keys' where id=2 waitfor delay '00:00:10' print '恭喜您,搶到了!!' end; else print '該券已經被搶了!!' commit tran
用代碼進行搶券,同個時間先后執行kxy和keys搶券
結果:
kxy

keys

持續更新,感謝關注!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/547161.html
標籤:SQL Server
