mysql中的樂觀鎖和悲觀鎖的簡介以及如何簡單運用。mysql
關於mysql中的樂觀鎖和悲觀鎖面試的時候被問到的機率仍是比較大的。面試
mysql的悲觀鎖:sql
其實理解起來很是簡單,當數據被外界修改持保守態度,包括自身系統當前的其餘事務,以及來自外部系統的事務處理,所以,在整個數據處理過程當中,將數據處於鎖定狀態。悲觀鎖的實現,每每依靠數據庫提供的鎖機制,可是也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,不然,即便在自身系統中實現了加鎖機制,也沒法保證外部系統不會修改數據。數據庫
來點實際的,當咱們使用悲觀鎖的時候咱們首先必須關閉mysql數據庫的自動提交屬性,由於MySQL默認使用autocommit模式,也就是說,當你執行一個更新操做後,MySQL會馬上將結果進行提交。安全
關閉命令爲:set autocommit=0;併發
悲觀鎖可使用select…for update實現,在執行的時候會鎖定數據,雖然會鎖定數據,可是不影響其餘事務的普通查詢使用。此處說普通查詢就是平時咱們用的:select * from table 語句。在咱們使用悲觀鎖的時候事務中的語句例如:性能
//開始事務索引
begin;/begin work;/start transaction; (三選一)事務
//查詢信息開發
select * from order where id=1 for update;
//修改信息
update order set name='names';
//提交事務
commit;/commit work;(二選一)
此處的查詢語句for update關鍵字,在事務中只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一條數據時會等待其它事務結束後才執行,通常的SELECT查詢則不受影響。
執行事務時關鍵字select…for update會鎖定數據,防止其餘事務更改數據。可是鎖定數據也是有規則的。
查詢條件與鎖定範圍:
一、具體的主鍵值爲查詢條件
好比查詢條件爲主鍵ID=1等等,若是此條數據存在,則鎖定當前行數據,若是不存在,則不鎖定。
二、不具體的主鍵值爲查詢條件
好比查詢條件爲主鍵ID>1等等,此時會鎖定整張數據表。
三、查詢條件中無主鍵
會鎖定整張數據表。
四、若是查詢條件中使用了索引爲查詢條件
明確指定索引而且查到,則鎖定整條數據。若是找不到指定索引數據,則不加鎖。
悲觀鎖的確保了數據的安全性,在數據被操做的時候鎖定數據不被訪問,可是這樣會帶來很大的性能問題。所以悲觀鎖在實際開發中使用是相對比較少的。
mysql的樂觀鎖:
相對悲觀鎖而言,樂觀鎖假設數據通常狀況下不會形成衝突,因此在數據進行提交更新的時候,纔會對數據的衝突與否進行檢測,若是發現衝突,則讓返回用戶錯誤的信息,讓用戶決定如何去作。
通常來講,實現樂觀鎖的方法是在數據表中增長一個version字段,每當數據更新的時候這個字段執行加1操做。這樣當數據更改的時候,另一個事務訪問此條數據進行更改的話就會操做失敗,從而避免了併發操做錯誤。固然,還能夠將version字段改成時間戳,不過原理都是同樣的。
例若有表student,字段:
id,name,version
1 a 1
當事務一進行更新操做:update student set name='ygz' where id = #{id} and version = #{version};
此時操做完後數據會變爲id = 1,name = ygz,version = 2,當另一個事務二一樣執行更新操做的時候,卻發現version != 1,此時事務二就會操做失敗,從而保證了數據的正確性。
悲觀鎖和樂觀鎖都是要根據具體業務來選擇使用,本文僅做簡單介紹。