mysql事务中的更新 - 隔离

I have following model

Inventory [product_name, quantity, reserved_quantity]

with data

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

What happens if following code is executed in multiple threads at the same time?

 $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();

Is it possible that the result will be?

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

It's not. Lets see what would be happening in the following scenario:

  1. The first transaction starts
  2. UPDATE Shirt => an exclusive row lock will be set on the record
  3. The second transaction starts
  4. The second transaction tries to UPDATE Shirt. As it would need to obtain a record lock it would wait as this record has already been locked by the first transaction
  5. The first transaction commits, the second one would resume execution and see the updated record

Of course it's only relevant to InnoDb and similar mysql engines. Please note that you're lucky enough that traversing the records in the same order. If it were not the case you might run into a deadlock