MySQL樂觀鎖為什么可以防止並發


問題引入

本文介紹的是最常用的也是mysql默認的innoDB引擎 Read committed隔離級別下事物的並發。這種情況下的事物特點是

讀:在一個事物里面的select語句 不會受到其他事物(不管其他事物有沒有commit)的影響。

寫:對一條記錄而言,一個事物一旦update一條記錄,其他事物只能等待這個事物commit才能update那條記錄

舉例並發分析:

比如表中num字段=10 需要根據num字段的數值做一些業務處理

事物A  begin   事物B begin  
select num 得到10   
根據結果10進行業務處理;  
處理完之后 num減一 update table set num = num-1;  
A 事物提交 commit; 此時num是9 此時A已經commit了
  select num 得到10 (此時的查詢不受其它事物的影響)
  根據結果10進行業務處理;
  處理完之后 num減一  update table set num = num-1;
  會把num更新成8。
 結論: B以num是10的基礎上 處理了眾多邏輯,但是到update的時候 用到的b確是9 

 

表格中 update table set num = num-1;會受到其他commit事物的影響(B事物把num從9更新成了8) 而select不會(查到的還是10)。

1利用樂觀鎖處理事物的並發

  數據庫增加一個鎖的處理列(版本號),查詢的時候多查一個版本號, update的時候 where條件附加一個版本號條件並且更新時候並且把版本號+1,處理流程

  1)select num,version from table;

  2)update table set num=num-1 ,version =version+1 where condition=? version=#{version

  3)Query OK, 1 rows affected (0.04 sec) | 注意:1 rows affected 

     update的時候 where條件附加一個版本號條件並且更新時候並且把版本號+1: update table set num=num-1 ,version =version+1 where condition=? version=#{version} 

  如果出現了查詢時候的版本號和where條件的版本號不一致 說明其他事物並發影響到了版本號 version,此時update語句的影響行數(Query OK, 1 rows affected (0.04 sec))是0 然后做異常處理。()

2把計算放到SQL中

當我們把計算邏輯(比如錢的增量)寫在SQL里面的時候 可以不用樂觀鎖,因為SQL增量時會讀到其他已經提交的事物。

注意:一條記錄,一個事物update還未提交的時候,其他時候只能等待這個事物commit完成才能update

樂觀鎖處理並發的原理 重點

當事物的隔離級別是REPEATABLE_READ情況下:當前事物不能select到並發事物中已經提交的事物。

當事物的隔離級別是READ COMMITTED情況下:當前事物select到並發事物中已經提交的事物。

1)一個事物中的select語句可能不會收到其他事物的影響,也就是可能查不到其他並發中未提交的事物(即使提交了 如果是REPEATABLE_READ也查不到)。所以兩個事物共同執行時產生了並發的沖突。

2)雖然這個被並發的字段通過select查不出來,但是在where條件語句中 這個字段會受到其他事物的影響 。所以可以利用這點 可以讀到並發事物影響的數據 ,從而做出判斷,防止並發。

補充:共享鎖與排他鎖

--共享鎖:對某一資源加共享鎖,自身可以讀該資源,其他人也可以讀該資源

(也可以再繼續加共享鎖,即 共享鎖可多個共存),但無法修改。要想修改就必須等所有共享鎖都釋放完之后。語法為:

select * from table lock in share mode

--排他鎖:對某一資源加排他鎖,自身可以進行增刪改查,其他人無法進行任何操作。語法為:

select * from table for update (A select for update的時候 B可以select 但不能select for update  排它鎖只有一把)

數據庫的增刪改操作默認都會加排他鎖,而查詢不會加任何鎖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM