Spring Data默认是否支持事务?无@Transactional时多操作事务疑问
Spring Data无@Transactional时的事务行为分析
你的假设完全正确:未在业务方法上添加显式@Transactional注解时,每个Spring Data Repository的方法调用都会开启并独立完成一个事务,Spring不会自动将关联的操作合并到单个事务中。
具体到你的代码场景:
public void findAndDelete(Long id) { User user = userRepository.findById(id); Long rowsAffected = userRepository.deleteById(id); }
userRepository.findById(id):这个方法本身被Spring Data默认的@Transactional(readonly = true)修饰,执行时会开启一个独立只读事务,查询完成后立即提交。userRepository.deleteById(id):该方法默认被@Transactional修饰,会开启另一个全新的写事务,执行删除操作后提交。
这两个操作之间存在明显的时间窗口,完全可能出现:
- 你的线程执行
findById查到用户存在; - 其他线程在这之后、你的线程执行
deleteById之前,删除了该用户; - 你的线程执行
deleteById时返回0(无行被影响),但代码已经认定用户存在,导致业务逻辑不一致。
如何确保操作原子性?
要让这两个操作在同一个事务中执行,必须在业务方法findAndDelete上添加@Transactional注解:
@Transactional public void findAndDelete(Long id) { User user = userRepository.findById(id); Long rowsAffected = userRepository.deleteById(id); }
此时整个方法的执行会被包裹在一个事务中,findById和deleteById都在这个事务内执行,避免了中间被其他线程干扰的问题。
另外补充:如果你的业务逻辑不需要先查询用户对象,直接调用deleteById(id)本身就是原子操作——数据库的删除语句本身具备原子性,能保证不会出现部分执行的情况,无需额外事务包裹。
内容的提问来源于stack exchange,提问作者Nipun Thathsara
相关产品推荐
相关产品推荐

