PHP 数据库事务控制完整示例

2次阅读

php数据库事务核心是确保操作全成功或全回滚,推荐用pdo(跨库、异常友好)或mysqli(仅mysql),需innodb引擎,避免隐式提交与耗时操作,配合try-catch实现闭环控制。

PHP 数据库事务控制完整示例

PHP 中使用数据库事务,核心是确保一组操作要么全部成功、要么全部回滚,避免数据不一致。最常用且推荐的方式是通过 PDO(支持多种数据库)或 mysqli(仅 MySQL)开启事务,并配合 beginTransaction()commit()rollback() 控制流程。

使用 PDO 实现事务控制(推荐)

PDO 支持跨数据库,自动关闭自动提交模式,语法清晰,异常处理友好。

  • 创建 PDO 实例时需关闭自动提交(默认已关,但显式设置更安全):$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
  • 调用 $pdo->beginTransaction() 显式开启事务
  • 执行多条 SQL(如 INSERT/UPDATE/delete),任一失败则手动 rollback()
  • 全部成功后调用 $pdo->commit()
  • 建议用 try-catch 包裹,捕获异常后自动回滚

示例代码:

try {     $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');     $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);     $pdo->beginTransaction(); <pre class='brush:php;toolbar:false;'>$pdo->exec("INSERT INTO accounts (name, balance) VALUES ('Alice', 1000)"); $pdo->exec("UPDATE accounts SET balance = balance - 200 WHERE name = 'Alice'"); $pdo->exec("UPDATE accounts SET balance = balance + 200 WHERE name = 'Bob'");  $pdo->commit(); echo "转账成功";

} catch (PDOException $e) { $pdo->rollback(); echo “操作失败:” . $e->getMessage(); }

使用 MySQLi 实现事务控制

MySQLi 面向对象风格同样支持事务,适用于纯 MySQL 环境。注意必须使用 mysqli_real_connect()构造函数连接,并确认引擎为 InnoDB(MyISAM 不支持事务)。

立即学习PHP免费学习笔记(深入)”;

  • 调用 $mysqli->begin_transaction() 开启事务(MySQLi 8.0+ 推荐)或 $mysqli->autocommit(false)
  • 执行 SQL 后检查每步是否成功($mysqli->affected_rows > 0 或用 errno 判断)
  • 出错时调用 $mysqli->rollback(),成功后 $mysqli->commit()

示例代码:

$mysqli = new mysqli('localhost', 'user', 'pass', 'test'); $mysqli->begin_transaction(); <p>if (!$mysqli->query("INSERT INTO logs (msg) VALUES ('start')") || !$mysqli->query("UPDATE users SET status = 'active' WHERE id = 123")) { $mysqli->rollback(); echo "事务回滚:" . $mysqli->error; } else { $mysqli->commit(); echo "事务提交成功"; }</p>

事务中的常见注意事项

事务不是万能的,实际使用中需避开几个典型陷阱:

  • 只对支持事务的存储引擎生效:MySQL 中必须用 InnoDB;MyISAM 或 Memory 引擎下 START TRANSACTION 无实际作用
  • 避免在事务中做耗时操作:如发送邮件、调用外部 API、大文件读写——会延长锁持有时间,影响并发性能
  • DML 以外的语句可能隐式提交:如 CREATE tableDROP TABLEALTER TABLE 在 MySQL 中会自动触发 COMMIT,导致事务中断
  • 连接生命周期内事务独立:每个数据库连接有自己事务上下文,不能跨连接共享或传播(分布式事务需额外方案如 XA 或业务层补偿)

简单封装一个事务助手类(可选增强)

为减少重复 try-catch,可封装一个轻量工具方法:

function transactional(callable $callback, PDO $pdo) {     $pdo->beginTransaction();     try {         $result = $callback($pdo);         $pdo->commit();         return $result;     } catch (Exception $e) {         $pdo->rollback();         throw $e;     } } <p>// 使用 transactional(function ($pdo) { $pdo->exec("INSERT INTO orders (...) VALUES (...)"); $pdo->exec("UPDATE inventory SET qty = qty - 1 WHERE id = 1"); }, $pdo);</p>

事务控制本质是数据一致性的守门人。只要确保开启、检查、提交/回滚三步闭环,再避开引擎和语句限制,就能稳定落地。

text=ZqhQzanResources