mysql樂觀鎖解決併發問題

博客1:
根本決解辦法只有一個:隊列,別的說的沒有用:https://www.cnblogs.com/sheseido/p/5038562.html


博客2:https://www.cnblogs.com/laoyeye/p/8097684.html
1、使用版本號實現樂觀鎖
版本號的實現方式有兩種,一個是數據版本機制,一個是時間戳機制。具體如下。

下單操作包括3步驟:

1.查詢出商品信息

select (status,status,version) from t_goods where id=#{id}

2.根據商品信息生成訂單

3.修改商品status爲2

update t_goods 

set status=2,version=version+1

where id=#{id} and version=#{version};

2、使用條件限制實現樂觀鎖

UPDATE t_goods
SET num = num - #{buyNum} 
WHERE
    id = #{id} 
AND num - #{buyNum} >= 0 
AND STATUS = 1

博客3:https://www.cnblogs.com/ssskkk/p/8673374.html

問題引入

當事務的隔離級別是REPEATABLE_READ情況下:當前事務不能select到併發事務中已經提交的事務。
當事務的隔離級別是READ COMMITTED情況下:當前事務能select到併發事務中已經提交的事務。
Mysql默認的事務隔離級別爲repeatable_read  :https://www.cnblogs.com/kangshuai/p/5735374.html
讀:在一個事物裏面的select語句 不會受到其他事務(不管其他事務有沒有commit)的影響。
寫:對一條記錄而言,一個事務一旦update一條記錄,其他事務只能等待這個事務commit才能update那條記錄。

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

1)一個事物中的select語句可能不會收到其他事物的影響,也就是可能查不到其他併發中未提交的事物(即使提交了 如果是REPEATABLE_READ也查不到)。所以兩個事物共同執行時產生了併發的衝突。
2)雖然這個被併發的字段通過select查不出來,但是在where條件語句中 這個字段會受到其他事物的影響 。所以可以利用這點 可以讀到併發事物影響的數據 ,從而做出判斷,防止併發。

所以可用下面方式處理(利用樂觀鎖處理事物的併發)

數據庫增加一個鎖的處理列(版本號),查詢的時候多查一個版本號, 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 然後做異常處理。()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章