數據庫通常允許多個用戶共享數據信息資源,所以必須對并發的事務進行控制,防止多用戶并發使用數據庫時造成數據錯誤,以保證數據的完整性。
事務的概念:
事務是用戶定義的一個數據庫操作序列,這些操作要么全做,要么全不做,是一個不可分割的很小的工作單位。
數據庫通過加鎖的方式控制并發,其中有兩種鎖:
共享鎖(S鎖):
又稱讀鎖,若事務T對數據對象A加S鎖,則事務T可以讀A但不能修改A,其他事務只能對A加S鎖,而不能加X鎖,直到事務T釋放A上的S鎖。這保證了其他事務可以讀A,而在事務T釋放A上的S鎖之前不能對A進行修改。
排它鎖(X鎖):
又稱寫鎖,若事務T對數據對象A加上X鎖,則事務T可以修改A也可以讀A,其他事務不能再對A加任何鎖,直到事務T釋放A上的鎖。這意味著在事務T釋放A上的鎖之前其他事務不能修改和讀取A。
在對數據進行加鎖時,需要約定并執行一些規則和協議,包括何時申請鎖、保持鎖的時間以及何時釋放等,這些規則就稱為封鎖協議:
一級封鎖協議:
事務T在修改數據A之前必須先對其加X鎖,直到事務結束才釋放。事務結束包括正常結束(COMMIT)和非正常結束(ROLLBACK)。
一級封鎖協議可以防止丟失修改,并保證事務T是可恢復的。使用一級封鎖協議可以解決丟失修改問題。在一級封鎖協議中如果僅僅是讀數據則不進行加鎖,因此不能保證可重復讀和不讀臟數據。
二級封鎖協議:
一級封鎖協議加上事務T在讀取數據A之前必須對其加S鎖,讀完后方可釋放S鎖。
二級封鎖協議除了防止丟失修改,還可以進一步防止讀臟數據。但在二級封鎖協議中讀完數據后就釋放鎖,所以不能保證可重復讀。
三級封鎖協議:
一級封鎖協議加上事務T在讀取數據A之前必須先對其加S鎖,直到事務結束才釋放。
三級封鎖協議除了防止丟失修改和讀臟數據之外,還進一步防止了不可重復讀。
三級封鎖協議的區別在于什么操作需要申請鎖,以及何時釋放。
MYSQL還提供了行級鎖、表級鎖和業級鎖
行級鎖:
引擎INNODB,僅對指定的一行記錄進行加鎖,這樣其他進程可以對同一個表中的其他記錄進行操作
表級鎖:
引擎MyISAM,即鎖住整個表可以同時讀,寫不行,在鎖定期間,其他線程無法對該表進行寫操作;如果是寫鎖,那么其他線程讀也不允許
頁級鎖:
引擎BDB,一次鎖定相鄰的一組記錄