Spring项目中调用数据库时是否必须添加@Transactional注解?
嗨,我完全懂你的困惑!其实你没做错——Spring里操作数据库不一定非要加@Transactional,这得看你的业务场景和具体操作是什么,下面给你拆解清楚:
单一数据库操作:不用手动加也没问题
比如你只是调用Spring Data JPA Repository的单条save()、findById()、delete()这类方法,或者Spring JDBC的单个update()操作,底层框架已经帮你处理了事务逻辑。拿Spring Data JPA来说,它的默认Repository方法都会被Spring代理,自动开启一个短暂的事务,执行完成后自动提交,所以你自己写的Service方法如果只包裹这类单一操作,确实不需要额外加@Transactional。多操作原子性需求:必须加注解
要是你的业务逻辑需要多个数据库操作同时成功或失败(比如先保存用户,再关联保存用户的收货地址),这时候就必须在对应的Service方法上添加@Transactional。没有这个注解的话,每个单独的操作会在自己的事务里提交,一旦中间某个操作失败,前面已经提交的操作就没法回滚,会导致数据不一致。另外,如果你需要自定义事务的传播行为(比如REQUIRES_NEW)、隔离级别(比如READ_COMMITTED),也得通过这个注解来配置。特殊场景:建议加注解优化
有些单一操作场景下,加@Transactional也有好处——比如给查询方法加上@Transactional(readOnly = true),数据库可以针对只读事务做性能优化(比如避免不必要的锁);或者你的方法里需要手动控制事务回滚(比如TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()),这时候也需要注解来开启事务上下文。
总结来说,你之前的做法完全没问题,只是要记住:当业务涉及多个数据库操作的原子性保证时,一定要补上@Transactional,其他场景根据需求灵活选择就好。
备注:内容来源于stack exchange,提问作者santi cazorla

