springdata+jpa service一个方法同一事物中执行delete和insert

场景:
在service中提供的一个方法是先将符合条件的数据全部删除,然后再将新的条件全部插入数据库中,这个场景需要保证service中执行两步:

  • 删除
  • 插入

这两步自然是在同一个事务中完成才是一个完整的操作,对于这个场景:

  • dao层:在jpa中使用delete操作,需要加上@Modifying@Transactional这两个注解,因为,@Modifying可以通知SpringData这是一个UPDATE或DELETE操作,而这两个操作需要使用事务,所以在dao层的delete方法上需要加上这两个注解
  • service层:需要在入口方法上加上@Transactional注解,用来保证两步操作在同一个事务内执行

这个时候会出现问题,因为执行SpringData的delete操作,并不会立即执行,而是等到service方法执行完成,才会提交事务,但是这样的话insert插入就会出现重复数据存在,不能重复插入的错误。

逻辑:
1、进入方法,开启事务
2、代码delete方法是jpa的delete方法,断点在此处发现并没有执行deleye的SQL语句,但是执行了一条select语句【可见自定义的delete方法是根据查到的数据再拼接sql在事务提交的时候才执行】
3、执行save的插入方法,执行了insert语句,报数据已存在
4、关闭事务

1)解决方案一:

仅更改service代码,手动调用flush()方法,让jpa在select出这个对象之后,拼接了delete语句,然后立刻执行sql作用到数据库。
delete之后,delete语句并没有执行,调用flush让他先把更改作用到数据库,再去执行save插入操作,虽然此刻事务依旧没有提交,但是delete语句已经执行
在这里插入图片描述

2)解决方案二:

写@Query语句,告诉jpa,我们要明确执行这条delete的sql语句,避免了让他去查一遍,拿到实体以后再拼接SQL语句,最后在方法结束,事务提交的时候才去执行delete语句。service不变。

这两种方式都可以解决delete操作和save操作在同一个事务中的原子性。
在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值