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. 解决idea单元测试@RunWith没有提示

    换成idea有一个月了,很多功能慢慢熟悉,今天想测试一下web程序 @RunWith没有提示查看一下原来是 scope 作用域 idea上不支持

  2. K8S Operator的开发与使用

    从应用角度考虑,为什么会出现如此多的Operator场景,为什么很多中间件和厂商都会提供基于Operator的部署方案,他的价值是什么? 随着时代的发展,企业应用部署环境从传统的物理机->虚拟机 ...

  3. Linux 系统下挂载linux 系统盘

    1应用背景:有时候系统崩溃无法修复,无法正常启动,而系统盘里面有需要的文件如log等需要拷贝出来,或者系统盘可以正常启动但是不方便用一台设备来启动这个系统盘.而直接将Linux系统盘接到windows ...

  4. MQ(创建MQ注意事项)

    创建MQ队列管理器时,需要注意的事项包括以下几点: 1) 队列管理器的日志类型以及日志文件的大小和个数,要根据用户数据量的大小.各个队列上的消息总容量,来计算日志的总容量,以免在系统运行过程中出现日志 ...

  5. excel编辑受限的密码保护破解

    录制一个宏并且执行: Public Sub 工作表保护密码() Const DBLSPACE As String = vbNewLine & vbNewLine Const AUTHORS A ...

  6. Vue中 ref、$refs区别与使用

    定义2个组件: 子组件ChildrenSubRef.vue: 1 <template> 2 <div> 3 4 </div> 5 </template> ...

  7. What is UDS Service 0x10 - Diagnostic Session Control ?

    Why need the UDS Service 0x10? ECU在正常工作时会处于某一个会话模式下,上电后会自动进入默认会话模式,所以ECU启动后我们不需要输入0x10 01来进入该会话模式.EC ...

  8. 【Apifox Helper】自动生成接口文档,IDEA+Apifox懒人必备

    @ 目录 前言 缘由 接口文档对接爽,整理起来真费脑 ⏲️本文阅读时长 约10分钟 前置条件 1. IDEA开发工具 2. Apifox(不必要) 主要目标 一秒生成接口文档 水图 IDEA中项目接结 ...

  9. 【经验分享】RTC 技术系列之视频编解码

    要了解什么是视频编解码,首先我们需要了解什么是视频. 视频归根结底是一系列连续的图像帧,当这些图像以一定速率播放时,人眼就会判断其是连续活动的,这样就构成了视频. 那为什么要进行视频编解码呢,因为视频 ...

  10. OpenAI Kubernetes 相关博文读后笔记

    一.概述 最近 ChatGPT 和其公司 OpenAI 特别火:ChatGPT 3, ChatGPT 3.5, New Bing, ChatGPT 4... 怀着学习的心态,这几天访问了 OpenAI ...