咱們在開發中也許都有感覺到,數據庫的併發操做會帶來許多問題,好比丟失更新、不可重複讀、讀髒數據(幽靈數據)等等,常見的好比自動售票系統,站點一、2同時讀出剩餘的票數n張,站點1售出一張票,並將n-1寫入數據庫,站點2也售出一張票並將n-1寫入數據庫,可是咱們都知道,應剩餘n-2張票,這就是典型的丟失數據更新的實例。爲避免該類問題的產生,咱們採用了封鎖機制,簡單點就是當一個線程要對數據庫進行相關操做時,先給數據庫加上適當的鎖,以此來避免其餘線程對數據庫進行操做而帶來的干擾。
併發操做之因此產生錯誤,是由於不一樣線程併發執行事務互相干擾形成的。因此咱們要對事務的併發操做進行控制,即併發控制。通常DBMS進行併發控制的方法是封鎖機制和事務機制。
封鎖就是對數據表、數據行等操做以前,先向系統請求對其加鎖,說通俗點就是操做以前先聲明權限。
封鎖的週期(環節):申請加鎖、得到鎖權限、釋放鎖權限
最基本的封鎖類型有兩種:排它鎖(Exclusive Locks,X鎖)和共享鎖(Share Locks,S鎖)。sql
排它鎖也稱獨佔鎖、寫鎖或X鎖,若sessionA得到某數據表的排他鎖權限,那麼sessionA只能對該表進行讀取或修改,其餘session既不能讀取也不能修改該表,更不能對該表加任何類型的鎖,直到sessionA釋放排它鎖權限。加鎖方式:lock tables tablename write;操做以下:
sessionA:
sessionB:
從上圖操做能夠看出sessionA得到ha表排它鎖權限之後sessionB執行訪問ha表操做之後並沒用顯示ha數據而是在等待sessionA釋放鎖權限。數據庫
共享鎖也稱讀鎖或S鎖,若sessionA得到某數據表的共享鎖權限,那麼任何session(包括sessionA)只能對該表進行讀取,不能修改該表,sessionA能夠繼續對該數據表加X鎖,其餘session能夠對該數據表繼續加S鎖但不能加X鎖,直到sessionA釋放共享鎖權限。加鎖方式:set tables tablename read;操做以下:
sessionA:
sessionB:
從上圖操做能夠看出,sessionA得到ha表共享鎖權限之後,sessionA和sessionB均可以訪問ha表,可是當sessionA想更改ha表時直接報錯(ERROR 1099 (HY000): Table ‘ha’ was locked with a READ lock and can’t be updated ha表有一個共享鎖不能被修改),sessionB更改ha表時並無顯示修改爲功,而是在等待sessionA釋放共享鎖權限。session
注意,在sessionA同時得到某數據表的S和X鎖權限時,sessionA只能select該數據表,其餘session將不能對該表進行任何操做,包括select、update、drop、delete、lock等等,直到sessionA釋放相關鎖權限。併發
MyISAM 在執行查詢語句(SELECT
)前,會自動給涉及的全部表加讀鎖,在執行更新操做 (UPDATE
、DELETE
、INSERT
等)前,會自動給涉及的表加寫鎖,這個過程並不須要用戶干預,所以,用戶通常不須要直接用LOCK TABLE
命令給MyISAM表顯式加鎖。ide
若是用戶想要顯示的加鎖可使用如下命令:線程
在用
LOCK TABLES
給表顯式加表鎖時,必須同時取得全部涉及到表的鎖。code在執行
LOCK TABLES
後,只能訪問顯式加鎖的這些表,不能訪問未加鎖的表;blog若是加的是讀鎖,那麼只能執行查詢操做,而不能執行更新操做。圖片
在自動加鎖的狀況下也基本如此,MyISAM 老是一次得到 SQL 語句所須要的所有鎖。這也正是 MyISAM 表不會出現死鎖(Deadlock Free)的緣由。事務