php - mysql事务中的更新——隔离

标签 php mysql concurrency transactions

我有以下模型

Inventory [product_name, quantity, reserved_quantity]

有数据

[Shirt, 1, 0] 
[Shorts, 10, 0]

如果以下代码同时在多个线程中执行会怎样?

 $changes = [
             ['name' => 'Shirt', 'qty' => 1],
             ['name' => 'Shorts', 'qty' => 1],
            ];
 $db->startTransaction();
 foreach($changes as $change){
     $rowsUpdated = $db->exec("UPDATE inventory 
            SET reserved_quantity = reserved_quantity + $change['qty']
            WHERE product_name = $change['name']
                 and quantity >= reserved_quantity + $change['qty']");
     if($rowsUpdated !== 1)
       $db->rollback();
       exit;
}
$db->commit();

有没有可能会是这样的结果?

[Shirt, 1, 2]
[Shorts, 10, 2]

最佳答案

不是。 让我们看看在以下情况下会发生什么:

  1. 第一个事务开始
  2. UPDATE Shirt => 将在记录上设置独占行锁
  3. 第二个交易开始
  4. 第二个 事务尝试UPDATE 衬衫。因为它需要获得记录锁,所以它会等待,因为该记录已被第一个事务锁定
  5. 第一个事务提交,第二个将恢复执行并查看更新的记录

当然只和InnoDb之类的mysql引擎有关。 请注意,您很幸运能够以相同的顺序遍历记录。如果不是这种情况,您可能会遇到 deadlock

关于php - mysql事务中的更新——隔离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37913466/

相关文章:

mysql - SELECT 语句中的 select_expr 子句有何用处?

java - 在 Java 中的多线程进程中更新 boolean 值

mysql - 单个字段上可靠的递减/递增所需的隔离级别

php - 拉维尔 5.1 : Cannot redeclare class Illuminate\\Contracts\\Support\\Arrayable

php - 使用 mysql 中的连接选择最近添加的数据

javascript - 单击按钮时 jQuery 返回 PHP 脚本

MySql 插入两个用外键连接的表

python - Flask THREADS_PER_PAGE 配置

php - 从零开始的 Wordpress 主题

php - POSTMAN chrome 应用程序发布的意外 '<' 错误