java - 事务 与 更新丢失的问题?
高洛峰
高洛峰 2017-04-18 10:29:12
0
4
546

先查询某一行的值,然后在更新这个值。在高并发的情况下,A 用户 查出来的值比如是 8,这时候按着8进行处理过程中,有另外的用户B,将这个值改成了10,当A用户再去更新的时候,就会造成数据的更新丢失。

通过对查询更新方法设置事务,加入防重复读的隔离级别,也是解决不了更新丢失问题的。防重复读,只能保证第一次读到是8,后面在怎么读这条记录,结果都是8。

解决这个问题,在mysql 数据库层面,只有用for update (悲观锁)或是乐观锁来锁住这一行记录。

问题是,对于事务与mysql悲观锁的理解有点混沌了。请高人给指点迷津。

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回覆(4)
大家讲道理

開啟事務狀態下mysql的預設隔離等級已經可以解決這個問題了吧。

阿神

例如
SET AUTOCOMMIT=0; BEGIN WORK;
SELECT quantity FROM products WHERE id=3 FOR UPDATE;
UPDATE products SET quantity = '1' WHERE idWO=3id;
你可以開啟事物。

接著在讀取這行記錄的時候給加上FOR UPDATE,把這條記錄給鎖住

使用FOR UPDATE 必須使用事務,因為不使用事務這句話近似於沒有FOR UPDATE,在事務中使用了FOR UPDATE後,在COMMIT/ROLLBACK之前,
其他會話如果讀取到這個id=3這行會一直等待,等待你的事務結束,並讀取新的行
其次FOR UPDATE 最好用在id = xx 或id in (xx,xx) 不然資料庫會降級為鎖定表

PHPzhong

WHERE裡加條件:

SELECT quantity FROM products WHERE id=3; 假设读到的quantity为8
UPDATE products SET quantity = '10' WHERE id=3 AND quantity=8;
大家讲道理

事務有4個級別
讀提交,讀未提交,可重讀,串行化
你仔細的描述一下你的需求,我看看!

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板