使用pdo连接mysql并开启事务,核心做法是调用 $pdo->begintransaction() 方法,随后执行sql语句,若全部成功则调用 $pdo->commit(),否则在异常捕获中调用 $pdo->rollback()。具体实现时,需先配置dsn、用户名和密码建立连接,并将 pdo::attr_errmode 设置为 pdo::errmode_exception 以确保错误能抛出异常供事务块捕获。

如何正确配置PDO以支持事务回滚?
必须将错误模式设置为异常模式,否则默认的错误处理机制不会抛出异常,导致 try-catch 块无法捕获数据库错误,进而无法触发回滚逻辑。同时,确保连接的驱动为MySQL即可,无需额外设置隔离级别,除非有特殊需求。

<?php $host = '127.0.0.1';
$db = 'test_db';
$user = 'root';
$pass = 'password';
$dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4";
try {
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
function transferMoney(PDO $pdo, int $fromId, int $toId, float $amount): bool {
try {
$pdo->beginTransaction();
// 检查余额
$stmt = $pdo->prepare('SELECT balance FROM accounts WHERE id = ? FOR UPDATE');
$stmt->execute([$fromId]);
$account = $stmt->fetch();
if (!$account || $account['balance'] prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?');
$stmt->execute([$amount, $fromId]);
// 入账
$stmt = $pdo->prepare('UPDATE accounts SET balance = balance + ? WHERE id = ?');
$stmt->execute([$amount, $toId]);
$pdo->commit();
return true;
} catch (Exception $e) {
$pdo->rollBack();
error_log($e->getMessage());
return false;
}
}
// 示例调用
transferMoney($pdo, 1, 2, 100.00);
?>
事务中哪些操作会导致隐式提交或失败?
在事务执行期间,如果执行了DDL语句(如 CREATE TABLE、ALTER TABLE),MySQL会自动提交当前事务,导致之前的更改无法回滚。此外,如果SQL语法错误或违反约束且未正确捕获异常,事务将处于未提交状态,需显式回滚。避免在事务块内执行非DML语句是保持事务完整性的关键。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。

当SQL语句执行失败时,事务状态如何变化?
当 prepare 或 execute 抛出异常时,beginTransaction() 标记的事务仍处于活跃状态,但已执行的更改尚未提交。此时必须进入 catch 块并调用 rollBack() 来撤销所有更改。若忘记调用回滚,连接将保持在一个未提交的事务中,可能锁定资源直到连接关闭或超时。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










