數據庫對於程序猿來 並不陌生,可是數據庫的鎖你知道多少?數據庫的鎖直接影響數據性能,在大併發的前提下,怎麼保證數據不被死鎖,提升數據庫性能?如何加鎖,什麼時候加鎖,加什麼鎖,你能夠經過hint手工強行指定,但大可能是數據庫系統自動決定的。這就是爲何咱們能夠不懂鎖也能夠寫SQL。程序員
下面咱們來簡單談一談數據庫中的鎖,以sqlserver 爲例:sql
數據庫鎖的種類:數據庫
1.共享鎖(Shared lock)session
何爲共享鎖,顧名思義意思就是資源共享,因此共享鎖之間 是沒有時間等待的能夠同時執行一條或多條查詢語句,共享鎖是用來讀的併發
數據庫規定同一資源上不能同時共存共享鎖和排他鎖。若是共享鎖在前必須等共享鎖執行完了才能加上排他鎖oracle
2.排他鎖(xlock) sqlserver
排他鎖,能夠簡單的理解爲 有限定條件的 更新或者查詢 若是對錶強制加排它鎖可使用 手寫關鍵字(xlock) 列入:select * from #t1 (xlock) 這裏就強制給資源加上了排他鎖,這樣作的好處就是 咱們在執行一些更新的sql語句時(列入事物,存儲等),排除了死鎖(holdlock)的可能性能
3.更新鎖(updlock)spa
爲解決死鎖,引入更新鎖。跟新鎖意思是:「我如今只想讀,大家別人也能夠讀,但我未來可能會作更新操做,我已經獲取了從共享鎖(用來讀)到排他鎖(用來更新)的資格」。一個事物只能有一個更新鎖獲此資格。 server
T1: begin select * from table(updlock) (加更新鎖) update table set column1='hello' (重點:這裏T1作update時,不須要等T2釋放什麼,而是直接把更新鎖升級爲排他鎖,而後執行update) T2: begin select * from table (T1加的更新鎖不影響T2讀取) update table set column1='world' (T2的update須要等T1的update作完才能執行)
共享鎖和更新鎖能夠同時在同一個資源上。這被稱爲共享鎖和更新鎖是兼容的。
4.死鎖(holdlock) holdlock 意思是加共享鎖,直到事物結束才釋放
5.獨佔鎖(Exclusive Locks)
這個簡單,即其它事務既不能讀,又不能改排他鎖鎖定的資源
列1
T1: update table set column1='hello' where id<1000 T2: update table set column1='world' where id>1000 假設T1先達,T2隨後至,這個過程當中T1會對id<1000的記錄施加排他鎖.但不會阻塞T2的update。
例2 (假設id都是自增加且連續的) T1: update table set column1='hello' where id<1000 T2: update table set column1='world' where id>900 如同例1,T1先達,T2馬上也到,T1加的排他鎖會阻塞T2的update.
6.意向鎖(Intent Locks)
意向鎖就是說在屋(好比表明一個表)門口設置一個標識,說明屋子裏有人(好比表明某些記錄)被鎖住了。另外一我的想知道屋子
裏是否有人被鎖,不用進屋子裏一個一個的去查,直接看門口標識就好了。
當一個表中的某一行被加上排他鎖後,該表就不能再被加表鎖。數據庫程序如何知道該表不能被加表鎖?一種方式是逐條的判斷該
表的每一條記錄是否已經有排他鎖,另外一種方式是直接在表這一層級檢查表自己是否有意向鎖,不須要逐條判斷。顯而後者效率高。
---------------------------------------- T1: begin tran select * from table (xlock) where id=10 --意思是對id=10這一行強加排他鎖 T2: begin tran select * from table (tablock) --意思是要加表級鎖 假設T1先執行,T2後執行,T2執行時,欲加表鎖,爲判斷是否能夠加表鎖,數據庫系統要逐條判斷table表每行記錄是否已有排他鎖, 若是發現其中一行已經有排他鎖了,就不容許再加表鎖了。只是這樣逐條判斷效率過低了。 實際上,數據庫系統不是這樣工做的。當T1的select執行時,系統對錶table的id=10的這一行加了排他鎖,還同時悄悄的對整個表 加了意向排他鎖(IX),當T2執行表鎖時,只須要看到這個表已經有意向排他鎖存在,就直接等待,而不須要逐條檢查資源了。
7.計劃鎖(Schema Locks)
---------------------------------------- alter table .... (加schema locks,稱之爲Schema modification (Sch-M) locks DDL語句都會加Sch-M鎖 該鎖不容許任何其它session鏈接該表。連都連不了這個表了,固然更不用說想對該表執行什麼sql語句了。 例15: ---------------------------------------- 用jdbc向數據庫發送了一條新的sql語句,數據庫要先對之進行編譯,在編譯期間,也會加鎖,稱之爲:Schema stability (Sch-S) locks select * from tableA 編譯這條語句過程當中,其它session能夠對錶tableA作任何操做(update,delete,加排他鎖等等),但不能作DDL(好比alter table)操做。
8.Bulk Update Locks
主要在批量導數據時用(好比用相似於oracle中的imp/exp的bcp命令)。不難理解,程序員每每也不須要關心,不贅述了。