Maison > Questions et réponses > le corps du texte
先查询某一行的值,然后在更新这个值。在高并发的情况下,A 用户 查出来的值比如是 8,这时候按着8进行处理过程中,有另外的用户B,将这个值改成了10,当A用户再去更新的时候,就会造成数据的更新丢失。
通过对查询更新方法设置事务,加入防重复读的隔离级别,也是解决不了更新丢失问题的。防重复读,只能保证第一次读到是8,后面在怎么读这条记录,结果都是8。
解决这个问题,在mysql 数据库层面,只有用for update (悲观锁)或是乐观锁来锁住这一行记录。
问题是,对于事务与mysql悲观锁的理解有点混沌了。请高人给指点迷津。
大家讲道理2017-04-18 10:31:12
L'activation du niveau d'isolation par défaut de MySQL dans l'état de transaction peut déjà résoudre ce problème.
阿神2017-04-18 10:31:12
Par exemple
SET AUTOCOMMIT=0;
SELECT quantité FROM products WHERE id=3 FOR UPDATE;
UPDATE products SET quantitative = '1' WHERE id=3; TRAVAIL ;
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
PHPz2017-04-18 10:31:12
OÙ Conditions de Riga :
SELECT quantity FROM products WHERE id=3; 假设读到的quantity为8
UPDATE products SET quantity = '10' WHERE id=3 AND quantity=8;
大家讲道理2017-04-18 10:31:12
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 !