事务边界要围绕业务动作设计
事务边界要围绕业务动作设计
事务不是哪里涉及数据库就随手加。事务边界设计不好,要么锁持有太久,要么状态更新不完整,要么异常后数据留下半成品。事务应该围绕一个完整的业务动作来设计。
先定义业务完成点
一个业务动作什么时候算完成,要先说清楚。比如创建订单,可能要写订单主表、写明细、扣减额度、记录操作日志。哪些步骤必须一起成功,哪些步骤可以异步补偿,要先区分。
只有完成点清楚,事务边界才有依据。
不要把外部调用包进长事务
如果事务里包含远程调用、文件上传、消息发送等慢操作,数据库锁可能被长时间持有。更稳的做法是先完成核心数据变更,再通过消息或补偿机制处理外部动作。
当然,这会带来一致性设计问题。工程上需要状态机、重试、幂等和告警配合,而不是简单把所有动作塞进一个大事务。
异常处理要谨慎
事务方法里捕获异常后如果没有继续抛出,可能导致本该回滚的操作被提交。这个问题很隐蔽,因为代码看起来处理了异常,实际却改变了事务语义。
我会把可预期的业务失败和不可预期的系统异常分开处理。业务失败返回明确结果,系统异常交给统一异常和事务机制处理。
复盘
事务边界体现的是业务理解。它不是注解使用技巧,而是要判断哪些变化必须成为一个整体,哪些变化可以异步、补偿或重试。