美文网首页小蒋同学
MySQL 事务及数据的一致性处理

MySQL 事务及数据的一致性处理

作者: 小蒋同学v | 来源:发表于2019-11-16 19:12 被阅读0次

    在工作中,我们经常会遇到这样的问题,需要更新库存,当我们查询到可用的库存准备修改时,这时,其他的用户可能已经对这个库存数据进行修改了,导致,我们查询到的数据会有问题,下面我们就来看解决方法。

    如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT ... UPDATE。

    举个例子

    假设商品表单 products 内有一个存放商品数量的 quantity,在订单成立之前必须先确定 quantity 商品数量是否足够( quantity > 0 ),然后才把数量更新为 1 。

    SELECT quantity FROM products WHERE id = 3; UPDATE products SET quantity = 1 WHERE id = 3;
    

    开启事务

    为什么不安全呢?

    高并发时会出现问题,如果我们需要在 quantity > 0 的情况下才能扣库存,假设程序在第一行 SELECT 读到的 quantity 是 2,但是当 MySQL 正准备要 UPDATE 的时候,可能已经有人把库存扣成 0 了,但是程序却浑然不知,将错就错的 UPDATE 下去了。因此必须利用事务机制来确保读取及提交的数据都是正确的。

    BEGIN WORK; SELECT quantity FROM products WHERE id = 3 FOR UPDATE;
    

    此时 products 数据中 id = 3 的数据被锁住,其它事务必须等待此次事务提交后才能执行。

    SELECT * FROM products WHERE id = 3 FOR UPDATE;
    

    确保 quantity 在事务中读取的数据是可靠的。

    UPDATE products SET quantity = '1' WHERE id = 3; COMMIT WORK;
    

    提交 (Commit) 事务,products 解锁。

    Tips:

    1. BEGIN / COMMIT 为事务的起始及结束点;
    2. 在事务进行当中,只有 SELECT ... FOR UPDATELOCK IN SHARE MODE 会等待事务结束后才执行,一般的 SELECT ... 则不受此影响。

    简单用法

    为了防止处理不当,根据业务实际情况,如果我们需要先查询,后更新数据的话,可以这样使用语句:

    UPDATE products SET quantity = '1' WHERE id = 3 AND quantity > 0;
    

    相关文章

      网友评论

        本文标题:MySQL 事务及数据的一致性处理

        本文链接:https://www.haomeiwen.com/subject/grtuictx.html