NEVER

不使用事务,如果当前事务存在,则抛出异常

验证:

@Service
public class PrService {
@Autowired
PrDao dao;
@Transactional
public void savea() {
dao.a();//保存第一条数据
saveb();
}
@Transactional(propagation = Propagation.NEVER)
private void saveb() {
dao.b();//保存第二条数据
int i=1/0;
}
}

写一个controller调用这个savea方法,页面看到的是/ by zero,数据库中两条数据都没有插入进去,都回滚了。照说设置了Propagation.NEVER,应该saveb方法根本执行不了,报never的错。为什么执行了呢?

因为是直接调用的saveb(),不是从代理对象上调用的方法,改成这样:

@Service
public class PrService {
@Autowired
PrDao dao; @Autowired
PrService prService; @Transactional
public void savea() {
dao.a();//保存第一条数据
prService.saveb();
} @Transactional(propagation = Propagation.NEVER)
private void saveb() {
dao.b();//保存第二条数据
int i=1/0;
}
}

注意这里是  prService.saveb()和前面不同,但是居然在  dao.b(); 这一行报了一个空指针的错误,这就诡异了,这个dao明明上a方法里面还有值的,你知道是为什么吗?

原来b方法的修饰符是private,导致代理对象无法继承这个方法。改成public

public void saveb()

再次测试,看到期待的报错了:

Existing transaction found for transaction marked with propagation 'never'

MANDATORY

当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。

这里把MANDATORY放在b方法上,就要把a方法上的transactional注解去掉,才能看到报错。

@Service
public class PrService {
@Autowired
PrDao dao; @Autowired
PrService prService; public void savea() {
dao.a();//保存第一条数据
prService.saveb();
} @Transactional(propagation = Propagation.MANDATORY)
public void saveb() {
dao.b();//保存第二条数据
}
}

或者直接把MANDATORY放在a方法上也会报错:

@Service
public class PrService {
@Transactional(propagation = Propagation.MANDATORY)
public void savea() {
}
}

报错如下

No existing transaction found for transaction marked with propagation 'mandatory'

REQUIRES_NEW

创建一个新事务,如果存在当前事务,则挂起该事务。

可以理解为设置事务传播类型为REQUIRES_NEW的方法,在执行时,不论当前是否存在事务,总是会新建一个事务。

现在写一个demo验证,a方法调用b方法,希望b方法里面异常了且事务回滚,a方法里面不回滚

下面验证:

同样为了在避免事务失效,在代理对象上调用方法,将被调用的方法放到一个单独的类中:

@Service
public class PrService {
@Autowired
PrDao dao; @Autowired
SaveBService saveBService; @Transactional
public void savea() {
dao.a();//插入第一条数据
saveBService.saveb();
}
}
@Service
public class SaveBService {
@Autowired
PrDao dao; @Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveb() {
dao.b();//插入第二条数据
int i = 1/0;
}
}

这里PrService的savea方法调用SaveBService的saveb方法,写一个controller访问savea方法,页面看到一个异常 / by zero,再检查数据库,两条数据都有没有插入进去。这是为什么呢?看上去第二个方法已经写到独立的类中了。

原来是因为b方法抛出的异常a方法没有捕获,又抛出去了,当然要回滚了。写个try catch就行:

    @Transactional
public void savea() {
dao.a();//插入第一条数据
try {
saveBService.saveb();
}catch (Exception e) {
System.out.println("some error");
}
}

再次测试,第二条数据没有插入,第一条数据插入到数据库了,页面也看不到报错了。

 
 

spring事务传播的Propagation.REQUIRES_NEW以及NEVER MANDATORY验证,及其失效的诡异问题的更多相关文章

  1. spring 事务传播(Propagation)

    propagation 一共有以下几种选项: 1. REQUIRED(默认): 使用当前的事务,如果当前没有事务,则自己新建一个事务,子方法必须运行在一个事务中:如果当前存在事务,则加入这个事务,成为 ...

  2. spring事务传播行为之使用REQUIRES_NEW不回滚

    最近写spring事务时用到REQUIRES_NEW遇到一些不回滚的问题,所以就记录一下. 场景1:在一个服务层里面方法1和方法2都加上事务,其中方法二设置上propagation=Propagati ...

  3. spring事务传播机制实例讲解

    http://kingj.iteye.com/blog/1680350   spring事务传播机制实例讲解 博客分类:   spring java历险     天温习spring的事务处理机制,总结 ...

  4. spring 事务传播机制

    spring 事务 传播机制 描述的 事务方法直接相互调用,父子事物开启,挂起,回滚 等的处理方式. 绿色的 那几个 我认为比较重要. 1 , @Transactional(propagation=P ...

  5. spring 事务传播行为实例分析

    Spring事务传播行为: spring特有的事务传播行为,spring支持7种事务传播行为,确定客户端和被调用端的事务边界(说得通俗一点就是多个具有事务控制的service的相互调用时所形成的复杂的 ...

  6. Spring 事务传播行为的使用

                                                                                                        ...

  7. 理解 spring 事务传播行为与数据隔离级别

    事务,是为了保障逻辑处理的原子性.一致性.隔离性.永久性. 通过事务控制,可以避免因为逻辑处理失败而导致产生脏数据等等一系列的问题. 事务有两个重要特性: 事务的传播行为 数据隔离级别 1.事务传播行 ...

  8. spring事务传播行为的思考

    1.问题 @TransactionConfiguration(transactionManager = "txManager", defaultRollback = false) ...

  9. spring事务传播行为讲解转载

    https://segmentfault.com/a/1190000013341344 前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为.事务传播行为是 ...

  10. spring事务传播属性和隔离级别

    猫咪咪的Java世界 spring事务传播属性和隔离级别 博客分类: Spring java编程   1 事务的传播属性(Propagation) 1) REQUIRED ,这个是默认的属性 Supp ...

随机推荐

  1. getopt函数使用说明

    一.查询linux命令手册: #include<unistd.h> #include<getopt.h> /*所在头文件 */ int getopt(intargc, char ...

  2. js延迟加载、js异步加载

    1.js延迟加载 (1)js延迟加载是js性能优化的一种方式 (2)作用:为了提高网页的加载速度 (3)原理:等网页加载完成之后再加载js文件 ··需要优化的原因:HTML元素是按照其在页面中出现的次 ...

  3. 程序猿、IT男、屌丝

    一个学计算机的,做了金融圈的朋友,对另外做硬件的朋友,如是说: [据说你写的程序代码,必须很浪的计算机才能运行] [ 以后还用写程序吗.不是ChatGPT直接可以出源代码吗?] 程序猿.IT男.屌丝. ...

  4. leetcode-1072 Flip Columns For Maximum Number of Equal Rows

    Given a matrix consisting of 0s and 1s, we may choose any number of columns in the matrix and flip e ...

  5. jacoco插件添加

    1.添加依赖 <dependency> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-p ...

  6. Maven项目的创建教程

    1.创建Maven项目 首先File->New新建一个Maven项目,选择相应地址保存,点击CREATE完成新建 2.改成Web项目 右键选择Add Framework Support... 再 ...

  7. 基于 Web SDK 实现视频通话场景 | 声网 SDK 教程

    声网视频 SDK 被广泛应用于多种实时互动场景中,例如视频会议.视频通话.音视频社交.在线教育等.为了让刚刚接触声网 SDK 的开发者,可以更顺畅地实现基础的视频通话功能,我们基于声网 Web SDK ...

  8. C++/Qt网络通讯模块设计与实现(三)

    上一节给大家从源码级别分析了SNetClient网络客户端的实现过程,详见​C++/Qt网络通讯模块设计与实现(二),并给大家留了一个疑问,即引入SNetClientRunning类是为了解决什么问题 ...

  9. 针对im输入框的一种处理方式

    针对im输入框的一种处理方式 <template> <div class="chatInput"> <!-- 通过contenteditable使普通 ...

  10. Git 操作命令清单 入门到精通(保姆级)

    一般来说,日常使用只要记住下图6个命令,就可以了.但是如果你想熟练使用它,要记住大概80个命令. 下面是常用的 Git 命令.几个专用名词的译名如下: Workspace:工作区 Index / St ...