Mysql 樂觀鎖和悲觀鎖

前言mysql

  1)在數據庫的鎖機制中介紹過,數據庫管理系統(DBMS)中的併發控制的任務是確保在多個事務同時存取數據庫中同一數據時不破壞事務的隔離性和一致性以及數據庫的一致性。sql

  2)加鎖是爲了解決更新丟失問題數據庫

更新丟失併發

  兩次更新同時進行,後一次更新覆蓋了前一次更新的狀況,更新丟失是數據沒有保證一致性致使的。spa

------事務A查詢餘額,此時balance=100-------
select balance from account where id = '1';
------事務B查詢餘額,此時balance=100-------
select balance from account where id = '1';
------事務A充值100,此時num=200-------
update account set balance = balance + 100 where id = 1; 
------事務B消費30,此時num=70-------
update account set balance = balance - 30 where id = 1;

  因爲A、B是同時進行的,形成了事務A被事務B覆蓋了。code

  解決辦法blog

    1)加鎖同步執行事務

    2)update時檢查同步

樂觀併發控制(樂觀鎖)io

  1)假設數據不會發生衝突,只在提交操做時檢查是否違反數據完整性。  

  2)樂觀鎖通常是爲數據增長一個版本標識實現。

------事務A查詢餘額,此時balance=100,version=1-------
select balance,version from account where = '1';
------事務B查詢餘額,此時balance=100,version=1-------
select balance,version from account where id= '1';
------事務A充值100,此時num=200-------
update account set balance = balance + 100,version = version + 1 where id = 1 and version = 1; 
------事務B消費30,此時失敗-------
update account set balance = balance - 30,version = version + 1 where id = 1 and version = 1;

 優勢與不足 

  • 樂觀鎖在失敗回滾的開銷較大

 

悲觀併發控制(悲觀鎖)

  1)假定數據會發生衝突,屏蔽一切可能違反數據完整性的操做。

  2)悲觀鎖通常利用mysql的排它鎖實現。

------事務A查詢餘額,此時balance=100併爲id=1加鎖-------
select balance from account where id = '1' for update;
------事務B查詢餘額,此時沒法加鎖失敗-------
select balance from account where id = '1' for update;
------事務A充值100,此時num=200-------
update account set balance = balance + 100 where id = 1; 

  優勢與不足

  • 悲觀鎖採用一鎖二查三更新的嚴謹策略。
  • 加鎖產生額外的開銷,容易產生死鎖;
  • 一個事務中鎖定了某行數據,其餘事務將等待。
相關文章
相關標籤/搜索