【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
随机推荐
- 算法导论 第七章 快速排序(python)
用的最多的排序 平均性能:O(nlogn){随机化nlogn} 原地址排序 稳定性:不稳定 思想:分治 (切分左右) 学习方式:自己在纸上走一遍 def PARTITION(A,p,r): x = ...
- JS中如何操作数组
背景:随笔中所应用到的代码来自于上一篇随笔,MVC&JQuery如何根据List动态生成表格,部分代码不再重复. 代码如下: $("#btnTan").click(func ...
- OpenSSL version mismatch. Built against 1000105f, you have 10001060
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=732940 http://ftp.debian.org/debian/pool/main/o/ope ...
- jeecg使用uploadify上传组件
在jeecg框架的系统内使用uploadify组件进行上传操作,有时无法正常发送请求,一直被重定向到登录请求,有可能使系统对上传操作进行了过滤,需要将这个上传请求放到非拦截序列里,才能正常使用. 第二 ...
- luogu2293 [JSOI2008]Blue Mary开公司
ref好像叫什么李超线段树?--这篇不是太通用-- #include <iostream> #include <cstdio> #include <cmath> u ...
- python 获得列表中每个元素出现次数的最快方法
import collections import numpy as np import random import time def list_to_dict(lst): dic = {} for ...
- Leetcode 467.环绕字符串中的唯一子字符串
环绕字符串中的唯一子字符串 把字符串 s 看作是"abcdefghijklmnopqrstuvwxyz"的无限环绕字符串,所以 s 看起来是这样的:"...zabcdef ...
- AtCoder Petrozavodsk Contest 001
第一场apc,5H的持久战,我当然水几个题就睡了 A - Two Integers Time limit : 2sec / Memory limit : 256MB Score : 100 point ...
- iOS AFNetWorking中block执行完后再执行其它操作
需求:同时进行两次网络请求,网络请求是异步的,在网络请求成功后进行其它的操作.两个网络请求是这样,一个网络请求中block执行完之后,再进行其它操作,也是一样的原理,只是这时候不需要线程组了,只需要信 ...
- 【Luogu】P4234最小差值生成树(LCT)
题目链接 能把LCT打得每个函数都恰有一个错误也是挺令我惊讶的. 本题使用LCT维护生成树,具体做法是对原图中的每个边建一个点,然后连边的时候相当于是将边的起点跟“边”这个点连起来,边的终点也跟它连起 ...