樂觀鎖是不對操作加鎖,但是默認是加鎖的?那樂觀鎖又是怎么實作的??
可以設定mysql對update這種陳述句不加鎖么??
uj5u.com熱心網友回復:
樂觀鎖是要在程式代碼實作的對表加一個時間戳的列
先select出來id和時間戳 然后再用id和時間戳來更新這行記錄
如果未能更新 說明時間戳變動,已被人更改
uj5u.com熱心網友回復:
我之前混淆了事務和鎖的定義。以mysql為例:在樂觀鎖中設定的是自動提交的,也就是一個陳述句就是一個事務,至于事務級別可能是提交讀或是未提交讀也是可以的。
基本步驟是:
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};
樂觀鎖中,上邊的每一個陳述句就是一個小事務,select都是可以隨便讀的,只有在更新時檢查。
不知道是不是我理解的這樣???希望指正。。。
uj5u.com熱心網友回復:
你說的我都知道,你沒有看懂我的困惑,不過我現在好像想通了,你幫我看看是不是2樓我理解的那樣。主要就是自動提交,每個陳述句是一個事務。
謝謝。。
uj5u.com熱心網友回復:
我知道你的困惑, 我也有跟你一樣的困惑, 請問你現在明白了嗎。。uj5u.com熱心網友回復:
其實這個困惑是兩件事, mysql對update陳述句加鎖, 是保證了陳述句級別的原子性.
而 樂觀鎖就是另一回事了, 舉個例子:
有一個商品表,有個欄位 商品數量, 買了商品, 就把商品表里的數量減1, 增加庫存就把數量加1.
那么有這么一個場景: A(一個商家), B(一個消費者)
A進了10件貨,count = count+10
B買了5件商品, count = count -5.
那么當這兩件事一塊來的時候, count 怎么保證事務性??
樂觀鎖的實作是在update的時候,判斷下version, version不對, 我再讀一遍, count最侄訓一致的.
uj5u.com熱心網友回復:
嗯嗯,是這樣的uj5u.com熱心網友回復:
說的很對,擼主解答了我的疑惑
uj5u.com熱心網友回復:
其實這樣理解是有問題的,mysql確實是有對單條的update陳述句默認加鎖實作,但是只是僅僅的單條update。比如UPDATE table1 SET num = num + 1 WHERE id=1;這樣一條update陳述句,其實內部是分為兩句,先查詢到id = 1 的行的num值,再對num值進行更新,a = SELECT * FROM table1 WHERE id=1; UPDATE table1 SET num = a.num + 1 WHERE id=1;很顯然,對num更新的操作進行了單條原子性的加鎖,但是對id查詢為1的操作并沒有加鎖。所以就會導致一個問題,在id = 1 查詢完畢后,得到舊的num值,這時候另一個事務將num更新并提交。我們再對num進行更新,就會導致update的覆寫。所以如果不想發生這種情況就需要對前面id = 1的加共享鎖或者是排他鎖。
再者就是使用樂觀鎖,使用update t_goods set status=2,version=version+1 where id=#{id} and version=#{version}; 在更新的時候會去找當前的version值,如果一致則更新。a = select * from t_goods where id=#{id} and version=#{version} update t_goods set status=2,version=a.version+1 where id=#{id} and version=#{version};如果中途被改變,則第二條更新陳述句的version修改,無法更新。第一條查詢陳述句只是查詢到對應version的值用于對第二條修改陳述句的更新。。
我也在學, 希望我說的夠清晰 , 所以是有加鎖和樂觀鎖 兩種方式保證并發的更新
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/8706.html
標籤:MySQL
上一篇:關于 VFP B/S 開發
