我有以下模型
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]
最佳答案
不是。 让我们看看在以下情况下会发生什么:
- 第一个事务开始
UPDATE
Shirt => 将在记录上设置独占行锁- 第二个交易开始
- 第二个 事务尝试
UPDATE
衬衫。因为它需要获得记录锁,所以它会等待,因为该记录已被第一个事务锁定 - 第一个事务提交,第二个将恢复执行并查看更新的记录
当然只和InnoDb之类的mysql引擎有关。 请注意,您很幸运能够以相同的顺序遍历记录。如果不是这种情况,您可能会遇到 deadlock
关于php - mysql事务中的更新——隔离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37913466/