
最近排查一个订单后台的问题,程序明明已经开启事务,中间步骤报错后接口也返回失败,但数据库里还是留下了部分订单数据。刚开始以为是 MySQL 事务没有生效,继续顺着代码看才发现,真正的问题是异常被提前"吃掉"了。
原来的写法是在事务里调用多个业务方法,其中一个方法内部用了 try catch。发生异常以后,这个方法只记录了一条日志,然后直接返回 false,并没有继续抛出异常。外层代码没有判断返回值,仍然执行到了 commit,所以前面已经写入的订单、客户记录全部被正式提交。
后来把事务边界重新整理,真正负责提交和回滚的地方只保留一层。内部方法出现异常时不再自己结束流程,而是把异常继续抛给外层统一处理。外层捕获后执行 rollback,同时记录订单号、执行步骤和异常信息。对于必须通过返回值判断的业务,也明确判断失败结果,避免程序继续往下执行。
做订单、充值、库存、佣金这类涉及多张表的数据时,事务不能只看有没有写 beginTransaction 和 rollback。更关键的是程序发生错误以后,控制流程到底有没有真正走到回滚。很多"事务失效"并不是数据库的问题,而是异常处理把原来的执行链打断了。
#PHP开发 #MySQL事务 #后台系统 #程序排查