是的,db::transaction() 中抛出 exception 或 error 会自动回滚,但普通 return 或静默失败不会;laravel 不支持真嵌套事务,内层 throw 由最外层捕获并回滚整个事务。

DB::transaction() 里抛异常就自动回滚吗
是的,但只对 Exception 和 Error 生效,普通 return 或静默失败不会触发回滚。
常见错误现象:在事务闭包里写了 if ($x) { return; },后面逻辑跳过,但事务已提交——因为没抛异常,Laravel 认为执行成功。
- 必须用
throw new \Exception()或throw new \RuntimeException()中断流程 -
DB::beginTransaction()+DB::commit()/DB::rollback()手动控制更明确,适合复杂分支判断 - Laravel 10+ 对
FatalError也支持自动回滚,但 PHP 8.0+ 才稳定,旧版本建议兜底捕获
嵌套事务在 Laravel 里怎么处理
Laravel 的 DB::transaction() 不支持真嵌套,第二次调用只是“加一层 try-catch”,不是新开事务。
使用场景:比如服务类 A 调用服务类 B,两者都写了 DB::transaction(),实际只有最外层生效。
- 内层事务里的
throw会向上冒泡,由最外层捕获并回滚整个事务 - 想隔离内层操作?改用
DB::unprepared('SAVEPOINT sp1')+DB::unprepared('ROLLBACK TO SAVEPOINT sp1') - 注意:MySQL 默认隔离级别是
REPEATABLE READ,SAVEPOINT 在长事务中可能引发锁等待,压测时留意SHOW ENGINE INNODB STATUS中的 lock info
事务里查不到自己刚插入的数据
不是 Bug,是事务隔离级别的正常表现。默认 REPEATABLE READ 下,事务启动瞬间的快照被固定,后续 SELECT 看不到本事务中未提交的 INSERT/UPDATE。
从一个Perl爱好者到一个Perl程序员。《Intermediate Perl》将教您如何把Perl作为编程语言来使用,而不仅只是作为一种脚本语言。 Perl是一种灵活多变、功能强大的编程语言,可以应用在从系统管理到网络编程再到数据库操作等很多方面。人们常说Perl让容易的事情变简单、让困难的事情变得可行。《Intermediate Perl》正是关于如何将技能从处理简单任务跃升到胜任困难任务的书籍。 本书提供对Perl中级编程优雅而仔细的介绍。由畅销的《学习Perl》作者所著,本书提供了《学习P
但 Laravel 的 DB::table()->insertGetId() 或模型 save() 后立刻 fresh() 能拿到数据,因为它们绕过了快照,直读最新行(前提是引擎支持,InnoDB 可以)。
- 如果非要
SELECT *查刚插的记录,用DB::select('SELECT * FROM users WHERE id = ?', [$id])—— 原生查询在当前事务上下文中读最新 - 避免在事务里依赖“查自己刚写的”,改为用返回值或变量暂存
- 切到
READ COMMITTED隔离级别能缓解,但需全局配置DB::connection()->getDoctrineConnection()->getDatabasePlatform()->setTransactionIsolationLevel(...),影响面大,不推荐只为这点改
事务超时导致死锁或连接堆积
MySQL 默认 innodb_lock_wait_timeout=50 秒,但 Laravel 的 PDO 连接还有 timeout 和 wait_timeout 两层限制,容易混淆。
典型现象:SQLSTATE[HY000]: General error: 2006 MySQL server has gone away 或 Lock wait timeout exceeded。
- 在
config/database.php的 MySQL 配置里加'options' => [PDO::ATTR_TIMEOUT => 10],控制单条语句等待上限 - 长事务(如导入万级数据)务必拆成小批量,每次
DB::transaction()控制在 100 条以内,配合DB::table()->upsert()减少 round-trip - 别在事务里做 HTTP 请求、文件读写、sleep() —— 这些会让连接空占着,触发
wait_timeout断连
事务不是银弹,跨服务、跨库、异步场景下,最终一致性比强一致更实际。该用消息队列补偿的时候,别硬扛在事务里塞逻辑。









