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

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

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

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

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

高洛峰
高洛峰

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

répondre à tous(4)
大家讲道理

L'activation du niveau d'isolation par défaut de MySQL dans l'état de transaction peut déjà résoudre ce problème.

阿神

Par exemple
SET AUTOCOMMIT=0;
SELECT quantité FROM products WHERE id=3 FOR UPDATE;
UPDATE products SET quantitative = '1' WHERE id=3; TRAVAIL ;

Vous pouvez allumer les choses.

Ensuite, ajoutez FOR UPDATE lors de la lecture de cet enregistrement, et verrouillez cet enregistrement.
Utiliser FOR UPDATE doit utiliser une transaction, car ne pas utiliser de transaction est similaire à ne pas utiliser FOR UPDATE, dans une transaction Après avoir utilisé FOR UPDATE, avant COMMIT/ROLLBACK,
si d'autres sessions lisent cette ligne avec id=3, elles attendront indéfiniment, attendront la fin de votre transaction et liront la nouvelle ligne
suivie de FOR UPDATE Il est préférable d'utiliser id = xx ou id dans (xx,xx) sinon la base de données sera rétrogradée vers une table de verrouillage

PHPzhong

OÙ Conditions de Riga :

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

Il existe 4 niveaux de transactions
Lecture validée, lecture non validée, relisible, sérialisée
Décrivez soigneusement vos besoins et laissez-moi y jeter un œil !

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal