以下是为您全新设计的PDO事务操作流程超详细解析,包含分步代码注释、执行流程图解和异常处理说明:
PDO事务操作全流程拆解(以用户注册为例)
业务场景:用户注册需同时写入users表和profiles表,任何一步失败都需完全回滚
1. 完整代码示例(带逐行解析)
<?php
// ===== 第1步:数据库连接 =====
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8';
$user = 'db_user';
$pass = 'db_password';
try {
// 创建PDO实例(启用异常模式)
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_AUTOCOMMIT => 0 // 重要!关闭自动提交
]);
// ===== 第2步:开启事务 =====
$pdo->beginTransaction();
echo "<pre>[事务状态] 事务已开启,进入原子操作模式</pre>";
// ===== 第3步:核心操作1 - 写入用户表 =====
$stmt1 = $pdo->prepare("INSERT INTO users(username, password) VALUES(?, ?)");
$stmt1->execute(['test_user', password_hash('123456', PASSWORD_DEFAULT)]);
$user_id = $pdo->lastInsertId();
echo "<pre>[操作1] 用户主表写入成功,ID: {$user_id}</pre>";
// ===== 第4步:核心操作2 - 写入资料表 =====
$stmt2 = $pdo->prepare("INSERT INTO profiles(user_id, email) VALUES(?, ?)");
$stmt2->execute([$user_id, 'test@example.com']); // 假设此处邮件已存在会触发唯一索引冲突
echo "<pre>[操作2] 用户资料表写入成功</pre>";
// ===== 第5步:提交事务 =====
$pdo->commit();
echo "<pre>[事务状态] 事务已提交,数据永久生效</pre>";
} catch (PDOException $e) {
// ===== 第6步:异常处理 =====
if ($pdo->inTransaction()) {
$pdo->rollBack();
echo "<pre>[事务状态] 事务已回滚,所有操作撤销</pre>";
}
echo "<pre>[错误报告] 注册失败: " . $e->getMessage() . "</pre>";
}
?>2. 执行流程解析表
3. 流程图解
开始 │ ├─1. 连接数据库(AUTOCOMMIT=0) │ ├─2. beginTransaction() │ │ │ ├─3. 操作1:写入users表 → 成功 │ │ │ └─4. 操作2:写入profiles表 → 失败! │ │ │ └─ 触发异常 │ │ ├─5. 正常流程:commit() ←┐ │ │ └─6. 异常流程:rollBack() ────────┘ │ └─ 输出结果
4. 关键点说明
连接配置
PDO::ATTR_AUTOCOMMIT => 0是原子操作的基础,相当于"游戏开始前先关闭自动存档"错误触发时机
主键冲突(如重复email)
字段类型不匹配(如字符串传入INT字段)
表不存在等SQL语法错误
事务状态检查
if ($pdo->inTransaction())确保只在活动事务中回滚,避免误操作
5. 实际执行结果模拟
场景1:操作2触发唯一索引冲突
<pre> [事务状态] 事务已开启,进入原子操作模式 [操作1] 用户主表写入成功,ID: 42 [事务状态] 事务已回滚,所有操作撤销 [错误报告] 注册失败: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'test@example.com' for key 'email' </pre>
场景2:全部操作成功
<pre> [事务状态] 事务已开启,进入原子操作模式 [操作1] 用户主表写入成功,ID: 43 [操作2] 用户资料表写入成功 [事务状态] 事务已提交,数据永久生效 </pre>
通过这种"显微镜级"的拆解,应该能彻底掌握PDO事务的每个技术细节。如果需要补充其他场景的解析,请随时告知!