SQl標(biāo)準(zhǔn)定義的四個(gè)隔離級(jí)別為: - readuncommited(讀未提交) - readcommited(不可重復(fù)讀) - repeatable read(可重復(fù)讀) - serializable(串行化)隔離度有多種實(shí)現(xiàn)方式,加鎖是其中的一種方式,其理解較為容易且能以開銷較小的方式確保數(shù)據(jù)庫系統(tǒng)中并發(fā)事物各自運(yùn)行時(shí),每個(gè)事務(wù)的運(yùn)行不受其他事務(wù)的影響。MySQL(InnoDB引擎)中在實(shí)現(xiàn)不同級(jí)別的隔離度時(shí),核心技術(shù)之一就是使用不同粒度的鎖。一、InnoDB中鎖的類型介紹(1)共享鎖(Shared Lock(S鎖))共享鎖可以允許當(dāng)前事務(wù)讀取一行數(shù)據(jù),由于讀不會(huì)改變數(shù)據(jù),故各個(gè)事務(wù)之間可以并發(fā)讀取數(shù)據(jù)。當(dāng)一個(gè)事務(wù)A獲取了行R的共享鎖,另外的事務(wù)B也可以立即獲得行R的共享鎖,這種情況稱為“鎖兼容”。設(shè)置共享鎖:SELECT* FROM USERWHEREID = 1 LOCK IN SHAREMODE;(2)排他鎖(ExclusiveLocks(X鎖))加了排他鎖的記錄,則不允許其他事務(wù)再向此數(shù)據(jù)表加S鎖或者X鎖。insert、update、delete操作,InnoDB會(huì)自動(dòng)給其加上排他鎖,對(duì)于select操作需要手動(dòng)設(shè)置排他鎖。設(shè)置排他鎖:SELECT * FROM USERWHEREID = 1 FOR UPDATE;共享鎖與排他鎖之間的兼容性如下:
事務(wù)A 事務(wù)B
共享鎖
排他鎖
共享鎖
兼容
不兼容
排他鎖
不兼容
不兼容
(3)意向共享鎖(IS鎖)事務(wù)在給數(shù)據(jù)行加共享鎖之前,會(huì)給數(shù)據(jù)行所在表也添加鎖,這個(gè)表級(jí)鎖就是意向共享鎖。如果需要對(duì)記錄 A 加共享鎖,那么此時(shí) InnoDB 會(huì)先找到這張表,對(duì)該表加意向共享鎖之后,再對(duì)記錄 A 添加共享鎖。(4)意向排他鎖(IX鎖)類似IS鎖,事務(wù)在給數(shù)據(jù)行加排他鎖前,會(huì)對(duì)數(shù)據(jù)行所在表添加意向排他鎖。當(dāng)一個(gè)事務(wù)對(duì)表添加意向排他鎖后,另外一個(gè)事務(wù)在加鎖前就會(huì)通過該表的意向排他鎖得知已經(jīng)有事務(wù)在對(duì)該表進(jìn)行獨(dú)占操作,從而等待。可以發(fā)現(xiàn),意向鎖是一種表級(jí)鎖,可較為方便地判斷表中是否存在被鎖定的數(shù)據(jù)行。假設(shè)意向鎖是一種行鎖(或不存在意向鎖),事務(wù)A對(duì)表中某一數(shù)據(jù)行加排他鎖且未提交,當(dāng)事務(wù)B欲對(duì)該表加表鎖時(shí),數(shù)據(jù)庫需逐行判斷表中是否存在被鎖定的數(shù)據(jù)行,執(zhí)行效率很低;但當(dāng)意向鎖作為表鎖出現(xiàn)時(shí),只需檢查一次表中是否存在意向鎖即可判斷當(dāng)前有無鎖定的數(shù)據(jù)行,性能大為提升。 在InnoDB中,意向鎖是引擎自動(dòng)維護(hù)的,用戶不能對(duì)其進(jìn)行操作,這種鎖可看作引擎對(duì)加鎖性能的優(yōu)化。另外,需要注意的是,InnoDB的行鎖是實(shí)現(xiàn)在索引項(xiàng)上的,所以只有通過索引條件檢索數(shù)據(jù),InnoDB才使用行級(jí)鎖,否則,InnoDB將使用表鎖。例如在teacher表中,id是主鍵(教師編號(hào)),但SQL語句中檢索條件為教師姓名:select * from teacher where name=‘Zhang Sand’ for update,此時(shí)不滿足上述行級(jí)鎖加鎖條件,則給整張表加鎖。(5)自增鎖(AUTO-INC Locks)自增鎖是一種特殊的表級(jí)鎖,當(dāng)一個(gè)事務(wù)正在向表中插入數(shù)據(jù)時(shí),其他事務(wù)都會(huì)被阻塞,確保插入數(shù)據(jù)的連續(xù)自增性。(6)表級(jí)鎖的兼容性表