【spring data jpa】使用spring data jpa时,关于service层一个方法中进行【删除】和【插入】两种操作在同一个事务内处理
场景:
现在有这么一个情况,就是在service中提供的一个方法是先将符合条件的数据全部删除,然后再将新的条件全部插入数据库中
这个场景需要保证service中执行两步
1.删除
2.插入
这两步自然是在同一个事务中完成才是一个完整的操作。
那么针对这个场景,看看注解怎么用
1》》先看dao层 链接:http://www.cnblogs.com/sxdcgaq8080/p/8984140.html
dao层也就是repository层的delete操作,也就是在jpa中使用delete操作,需要加上
@Modifying
@Transactional
这两个注解,因为
1.@Modifying 以通知 SpringData, 这是一个 UPDATE 或 DELETE 操作
2.UPDATE 或 DELETE 操作需要使用事务,所以在dao层的delete方法上需要加上这两个注解

2》》然后说service层的这个方法中的两步走
需要在入口方法上加上
@Transactional
注解,用来保证两步操作在同一个事务内执行

这样的情况,是第一个事务注解起作用,delete方法上的注解是为了支持delete操作才加的
======================================
但是这个时候依旧是会出问题的,因为执行spring data的delete操作,并不会立即执行,而是等到service方法执行完成,才会提交事务。但是这样的话 insert插入就会出现 重复数据存在,不能重复插入的错误!!!
理一下这个逻辑:【spring的事务@Transactional底层是spring AOP】
1.进入方法,开启事务
2.代码delete方法是jpa的delete方法,断点在此处发现并没有执行delete的sql语句,但是执行了一条select语句。【可见自定义的delete方法是根据查到的数据再拼接sql在事务提交的时候才执行】
3.执行save的插入方法,执行了insert语句,报错数据已经存在,不能重复插入
4.关闭事务
而我们想要delete在insert之前就执行了,并且还要保证delete和insert是在同一个事务中进行的。
解决方案1:
仅更改service代码
手动调用flush()方法,【让jpa在selete出这个对象之后,拼接了delete语句,然后即刻执行sql作用到数据库】,这样在下面insert的时候delete已经执行了,就不会出现重复数据的错误。

解决方法2:
就是写@Query("JPQL语句")
告诉jpa,我要明确执行这条delete的sql语句,避免了【让它去查一遍,拿到实体以后再拼接SQL语句,最后在方法结束,事务提交的时候才去执行delete语句】,这个时候已经迟了。
这个时候是不会执行select语句的,只执行了delete和insert
仅改变dao层代码

service不变如下

这两种方式都可以解决 delete操作和save操作在同一个事务中的原子性。
但是第一种方法相当于是多做了一步,就是执行delete的时候会去数据库selete一次。。。而第二种方法则会直接执行delete语句,不会执行selete。
【spring data jpa】使用spring data jpa时,关于service层一个方法中进行【删除】和【插入】两种操作在同一个事务内处理的更多相关文章
- 当 IDENTITY_INSERT 设置为 OFF 时,不能向表 'OrderList' 中的标识列插入显式值
问题描述:在SQL SERVER 2008中,向数据表中字段插入数据时,会报错,错误如下: 当 IDENTITY_INSERT 设置为 OFF 时,不能向表 'OrderList' 中的标识列插入显式 ...
- 当 IDENTITY_INSERT 设置为 OFF 时,不能向表 '#TT' 中的标识列插入显式值。 sql server 临时表
当 IDENTITY_INSERT 设置为 OFF 时,不能向表 '#TT' 中的标识列插入显式值.我是在SqlServer写存储过程中遇到的这个错误,当时就心想:临时表怎么会有主键呢,我也没有设置主 ...
- 当 IDENTITY_INSERT 设置为 OFF 时,不能为表‘XXX’中的标识列插入显式值。
在创建事务复制时,很多时候不一定使用快照进行初始化,而是使用备份还原初始化.当对有标识列(即identity的自增列)的表进行复制的时候,使用备份还原初始化搭建起来的复制常常就会报错,即:当 IDEN ...
- The Data Way Vol.4|开源是创造软件诸多方法中最好的一种形式
关于「The Data Way」 「The Data Way」是由 SphereEx 公司出品的一档播客节目.这里有开源.数据.技术的故事,同时我们关注开发者的工作日常,也讨论开发者的生活日常:我们聚 ...
- Spring main方法中怎么调用Dao层和Service层的方法
在web环境中,一般serviceImpl中的dao之类的数据库连接都由容器启动的时候创建好了,不会报错.但是在main中,没有这个环境,所以需要获取环境: ApplicationContext ct ...
- [Bug]当IDENTITY_INSERT设置为OFF时,不能为表“xx”中的标识列插入显示的值
写在前面 在设计数据库表时,将主键设置为了自增的.在使用linq to sql的时候,添加数据,出现此错误. 解决方案 找到linq to sql生成的**.dbml文件,在对应的表上面右键修改其属性 ...
- 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'tb_MyInvoices' 中的标识列插入显式值
默认情况下,IDENTITY_INSER就是off 这种情况下,你写insert 语句时,identity栏位,不要写值,系统会自动帮你写入. 举例说明: ,),dt datetime,pay int ...
- 通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
WinForm 上放置的控件多了或者有大背景图,窗体加载时就会闪烁,对于一般的闪烁,设置 DoubleBuffer=True或许有一点改善,要立竿见影的解决可以重载 CreateParams 使用 W ...
- 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'T_Shell' 中的标识列插入显式值。
--允许将显示值插入表的标识列中-ON:允许 OFF:不允许set identity_insert T_shell ONset identity_insert T_Shell OFF
随机推荐
- BNU 3692 I18n 模拟
题意: 在一篇文章中,单词可以缩写.例如单词Internationalization可以缩写为I18n,缩写的两端是原单词的首尾字母,中间的数字是被省略的字母的个数. 现在给你一篇缩写的文章,输出展开 ...
- Win磁盘MBR转换为GUID
title: Win磁盘MBR转换为GUID date: 2018-09-02 11:52:32 updated: tags: [windows,记录,折腾] description: keyword ...
- 记一次运行spark程序遇到的权限问题
设置回滚点在本地运行时正常,在集群时就报错,后来是发现ceshi这个目录其他用户没有写的权限,修改其他用户的权限就好了 hdfs dfs - /ceshi
- linux dd命令创建一定大小的文件
http://www.cnblogs.com/jikexianfeng/p/6103500.html
- Eclipse调试程序及项目的导入导出
Eclipse调试程序 调试概述: ① 调试就是测试程序的方法,主要的目的就是解决程序的逻辑问题,流程是:发现问题.修改问题.正确执行; ② 以前我们可以使用System.out.printl ...
- 【转】简要分析unity3d中剪不断理还乱的yield
在学习unity3d的时候很容易看到下面这个例子: 1 void Start () { 2 StartCoroutine(Destroy()); 3 } 4 5 IEnumerator Destroy ...
- bzoj 4184 shallot 时间线建线段树+vector+线性基
题目大意 n个时间点 每个时间点可以插入一个权值或删除一个权值 求每个时间点结束后异或最大值 分析 异或最大值用线性基 但是线性基并不支持删除操作 我们可以对时间线建一棵线段树 离线搞出每个权值出现的 ...
- hdu 3320 计算几何(三维图形几何变换)
openGL Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- 头条PC端的鼠标经过图片放大效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- NERDTree
What's NERDTree : A tree explorer plugin for vim. Install : Using Vundle on .vimrc " for ...