php中mysql手动提交事务和在for循环里进行事务控制及声明式事务的使用
封面图
•
2025-10-15
•
PHP
173
0
0
0
在 PHP 中操作 MySQL 数据库时,**事务控制**是非常重要的,尤其是在处理多条 SQL 语句需要保证“全部成功”或“全部失败”的场景中。PHP 提供了多种方式来进行事务控制,包括: 1. **手动提交事务** 2. **在 `for` 循环中进行事务控制** 3. **声明式事务(使用 PDO 的 `beginTransaction()`、`commit()`、`rollBack()`)** 下面我将分别介绍这三种方式,并给出示例代码。 --- ## ✅ 1. 手动提交事务(使用 `mysql_query` 或 `mysqli`) > 注意:`mysql_*` 函数已弃用,推荐使用 `mysqli` 或 `PDO`。 ### 示例(使用 `mysqli`): ```php <?php $host = 'localhost'; $user = 'root'; $pass = ''; $db = 'test_db'; // 连接数据库 $conn = new mysqli($host, $user, $pass, $db); if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } // 开始事务 $conn->begin_transaction(); try { // 第一条 SQL $sql1 = "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')"; if (!$conn->query($sql1)) { throw new Exception("插入用户失败"); } // 第二条 SQL $sql2 = "UPDATE accounts SET balance = balance - 100 WHERE user_id = 1"; if (!$conn->query($sql2)) { throw new Exception("更新账户失败"); } // 提交事务 $conn->commit(); echo "事务提交成功!"; } catch (Exception $e) { // 回滚事务 $conn->rollback(); echo "事务回滚,错误信息:" . $e->getMessage(); } ``` --- ## ✅ 2. 在 `for` 循环中进行事务控制 当你需要在一个循环中执行多个数据库操作,并希望这些操作作为一个整体来处理(要么都成功,要么都失败),可以使用事务。 ### 示例: ```php <?php $host = 'localhost'; $user = 'root'; $pass = ''; $db = 'test_db'; $conn = new mysqli($host, $user, $pass, $db); if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } $conn->begin_transaction(); try { $data = [ ['name' => 'Bob', 'email' => 'bob@example.com'], ['name' => 'Charlie', 'email' => 'charlie@example.com'], ['name' => 'David', 'email' => 'david@example.com'] ]; foreach ($data as $item) { $stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)"); $stmt->bind_param("ss", $item['name'], $item['email']); $stmt->execute(); if ($stmt->errno) { throw new Exception("插入数据失败: " . $stmt->error); } } $conn->commit(); echo "所有数据插入成功!"; } catch (Exception $e) { $conn->rollback(); echo "事务回滚,错误信息:" . $e->getMessage(); } ``` --- ## ✅ 3. 声明式事务(使用 PDO) PDO 是一个更现代、更灵活的数据库抽象层,支持多种数据库(如 MySQL、PostgreSQL 等)。它提供了更清晰的事务控制方式。 ### 示例(使用 PDO): ```php <?php $host = 'localhost'; $db = 'test_db'; $user = 'root'; $pass = ''; try { $pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 开始事务 $pdo->beginTransaction(); // 第一条 SQL $pdo->exec("INSERT INTO users (name, email) VALUES ('Eve', 'eve@example.com')"); // 第二条 SQL $pdo->exec("UPDATE accounts SET balance = balance - 50 WHERE user_id = 1"); // 提交事务 $pdo->commit(); echo "事务提交成功!"; } catch (PDOException $e) { // 回滚事务 $pdo->rollBack(); echo "事务回滚,错误信息:" . $e->getMessage(); } ``` --- ## 🧠 小结对比 | 方法 | 是否推荐 | 特点 | |------|----------|------| | 手动提交事务(`mysqli`) | 推荐 | 灵活,适合简单事务 | | `for` 循环中事务控制 | 推荐 | 适用于批量操作 | | 声明式事务(`PDO`) | 推荐 | 更现代、安全、易维护 | --- ## 🔒 事务注意事项 - **事务必须开启**:`begin_transaction()` 或 `START TRANSACTION` - **事务必须提交**:`commit()` - **事务失败时必须回滚**:`rollBack()` - **避免长时间占用事务**:会影响数据库性能 - **确保 SQL 语句正确**:否则事务会失败 --- 如果你有具体的业务场景(比如批量导入、订单处理等),我可以帮你设计更合适的事务控制逻辑。欢迎继续提问!
上一篇:
PHP隐藏部分字符串(如:姓名、用户名、身份证、IP、手机号等)
下一篇:
47001 data format error hint 解析 JSON/XML 内容错误
标题录入,一次不能超过6条
留言
评论