如何在MySQL中使用事务来避免;丢失的更新;?

如何在MySQL中使用事务来避免;丢失的更新;?,mysql,sql,concurrency,transactions,Mysql,Sql,Concurrency,Transactions,当两个不同的事务试图进行更新时,会发生更新丢失 同时更新数据库中同一行上的同一列 时间通常,一个事务会更新一个数据库中的特定列 这是一场特别的争吵,而另一场争吵很快就开始了 在更新相同的值之前,看不到此更新。结果 然后,第一个事务的数据被“丢失”,因为它只是被覆盖 在第二笔交易之前-- 这也称为“竞争条件”。你的问题已经有了答案:你“使用一个事务”,你工作吗,然后在每个线程中提交事务。现在,问题的实质是: 您的表必须是if类型InnoDB 默认情况下,MySQL连接使用每个命令一个事务,基本上

当两个不同的事务试图进行更新时,会发生更新丢失 同时更新数据库中同一行上的同一列 时间通常,一个事务会更新一个数据库中的特定列 这是一场特别的争吵,而另一场争吵很快就开始了 在更新相同的值之前,看不到此更新。结果 然后,第一个事务的数据被“丢失”,因为它只是被覆盖 在第二笔交易之前--

这也称为“竞争条件”。你的问题已经有了答案:你“使用一个事务”,你工作吗,然后在每个线程中提交事务。现在,问题的实质是:

  • 您的表必须是if类型InnoDB
  • 默认情况下,MySQL连接使用每个命令一个事务,基本上在每次写入后自动提交数据。您需要
    启动事务
    或禁用自动提交:
    $mysqli->autocommit(FALSE)
  • 您需要注意操作的结果,并对错误进行
    回滚
    ,然后停止正在执行的操作
  • 您确实必须记住在完全完成更改后提交更改,否则系统会认为有错误并为您回滚

    • 您有两种可能

    • 在悲观锁定的情况下,如果要更新刚读取的数据,请选择更新。然后,只有一个人可以读取记录,直到当前事务完成,其他试图选择更新的人必须等待
    • 在乐观锁定的情况下,您制定update语句,以便在select和update之间发生更改时,不会发生更新。在您的情况下,您可以使用以下方法完成此操作:

      UPDATE product set quantity = 10 
             where id = 1 and quantity = <original quantity -- 7>
      
      更新产品集数量=10
      其中id=1,数量=
      
      如果没有更新预期数量的记录(通常为1),因为另一个过程同时更新了数量,则必须在更新之前重复选择。 你怎么知道,有多少记录被更新了?这取决于您执行db请求所使用的技术,但根据我的经验,每个Sql Dbms都会将该信息返回给其客户机

    • 或者

      设置事务隔离级别可重复读取

      --并遭受一些死锁和性能损失
      --没有看上去那么糟糕,但取决于您的需要
      --可重复读取是InnoDB的默认级别

      选择以进行更新

      --好吧,你编写了代码,你知道哪些选项需要将其他选项锁定在外
      --这假设您的隔离级别为READ\u COMMITTED

      关于隔离级别的更多信息可以在MySql文档中找到(这次简短明了)

      据我所知,MySQL中的可重复读取隔离级别无法防止更新丢失。所以你的第一个选择不起作用。