首页  >  文章  >  数据库  >  MySQL 事务与 PDO 可以并发运行而不会发生干扰吗?

MySQL 事务与 PDO 可以并发运行而不会发生干扰吗?

Linda Hamilton
Linda Hamilton原创
2024-10-28 04:16:02829浏览

 Can MySQL Transactions with PDO Run Concurrently Without Interference?

用 PDO 探索 MySQL 事务的并发

数据库事务的话题经常伴随着缩写词 ACID,代表原子性、一致性、隔离性和持久性。简单来说,事务保证数据库操作可靠地执行,并且不受其他并发连接的影响。

但是,一个问题出现了:多个 PHP 脚本可以同时运行事务而互不干扰吗?要理解这一点,请考虑以下场景:

假设一个名为“employees”的表具有两个字段:“id”和“salary”。两个脚本 script1.php 和 script2.php 同时执行以下代码:

<code class="php">$conn->beginTransaction();

$stmt = $conn->prepare("SELECT * FROM employees WHERE name = ?");
$stmt->execute(['ana']);
$row = $stmt->fetch(PDO::FETCH_ASSOC);

$salary = $row['salary'];
$salary = $salary + 1000;

$stmt = $conn->prepare("UPDATE employees SET salary = {$salary} WHERE name = ?");
$stmt->execute(['ana']);

$conn->commit();</code>

在这种情况下“ana”的最终工资是多少?

答案取决于为 MySQL InnoDB 表引擎配置的隔离级别。 InnoDB 支持 SQL 标准指定的四种隔离级别:

  • 未提交读
  • 已提交读
  • 可重复读
  • 可序列化

默认情况下,MySQL 使用“已提交读”隔离级别。在此级别中,结果将是 11000。这是因为 script1.php 和 script2.php 在提交之前读取相同的数据。

如果使用“可序列化”隔离级别,结果将为 12000。这是因为 Serialized 可确保事务按顺序执行并防止其他事务干扰锁定的数据。

在给定的示例中,事件顺序为:

  1. script1.php 选择data
  2. script2.php 选择数据
  3. script1.php 更新数据
  4. script2.php 更新数据
  5. script1.php 提交
  6. script2.php 提交

通过“读取已提交”隔离,两个脚本在提交之前都会读取相同的数据。因此,工资的增加不是孤立的,而是应用了两次,导致增加了 2000。

通过“Serialized”隔离,第一个事务 (script1.php) 锁定“ana”的行,当它选择数据。当 script2.php 尝试选择相同的数据时,它将等到第一个事务提交。这样可以保证数据在读取时不会被其他事务修改,并且工资的增加只应用一次,结果增加了 1000。

因此,同时事务之间的干扰取决于隔离级别和具体的操作顺序。了解不同隔离级别的含义对于确保事务在并发环境中按预期运行至关重要。

以上是MySQL 事务与 PDO 可以并发运行而不会发生干扰吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn