Spring事务传递性探讨
本篇主要讨论下面几点获取【下载地址】 :
一: Spring 事务的传递性介绍
二: 第三方调用含有事务的Service抛异常方法探讨
一: Spring 事务的传递性介绍
事务传播行为,所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价TransactionDefinition.PROPAGATION_REQUIRED。
这里需要指出的是,前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED是 Spring 所特有的。以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部的事务提交,才能引起内部事务的提交,嵌套的子事务不能单独提交。如果熟悉 JDBC 中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,一个事务中可以包括多个保存点,每一个嵌套子事务。另外,外部事务的回滚也会导致嵌套子事务的回滚。
二: 第三方调用含有事务的Service抛异常方法探讨
假设术语如下:调用方Conumer, 调用Service的methodA, methodA调用Service的 methodB
a)methodA 传播属性为required, methodB传播属性为required, 代码如下
- public void methodA() {
- try {
- methodB();
- } catch(Exception e) {
- process();
- }
- otherOperation;
- }
发现Consumer调用MethodA的时候出现了运行时异常,UnexpectedRollbackException: “Transaction rolled back because it has been marked as rollback-only”。这是为什么呢?
网上搜索了下,终于发现了一个合理的解释。当MethodA调用MethodB的时候,且两个方法都为required属性,则methodA和methodB共享一个事务,当methodB抛出了异常,则共享事务回滚,但是被MethodA catch了,而MethodA又没有及时抛出异常,则MethodA正常执行到最后的时候,则会做提交事务的操作,但是事务已经被回滚了,所以才出现了上面的异常。
既然这样,小弟就开始YY了一下,哪些情况会使调用方没有这个异常呢?经过与小伙伴们的思维碰撞,发现有一下几个方法。
b) MethodA 不加事务,所以执行到最后就不会commit,SUPPORTS和NOT_SUPPORTED都可以实现这种功能。
c) MethodB 设置不共享事务,拥有自己单独的事务。验证发现,REQUIRES_NEW可以实现这种功能。
然后又YY了下,既然一个回滚的事务不能提交了,那么这个回滚的事务可以重复回滚吗?
d) MethodA 调用MethodB,如果MethodA不catch MethodB,则调用方会怎么样?很简单当然直接捕获到MethodB的异常了,但是感觉这个场景不能完全反应初回滚的事务是否可以重复回滚。代码如下:
- public void methodA() {
- methodB();
- otherOperation;
- }
e) 还有什么场景可以模拟回滚的事务是否可以再回滚呢?看,代码如下:
- public void methodA() {
- try {
- methodB();
- } catch(Exception e) {
- process();
- }
- try {
- methodB();
- } catch(Exception e) {
- process();
- }
- System.out.println("**************");
- otherOperation;
- }
第一个MethodB已经回滚了共享的事务,第二个MethodB同样会抛出异常回滚共享的事务,如果执行了后面的System.out,则说明事务可以多次回滚。测试发现打印出来了后面的SysOut的内容,所以猜测可能是这样回滚事务的时候如果发现事务已经回滚,则直接跳过。
Spring事务传递性探讨的更多相关文章
- Spring事务控制和传递性理解
1.在同一类方法间相互调用,如果调用方无事务控制,被调用方有事务控制,则被调用方也无事务 原因:外部经过spring容器调用service的方法事务才生效,service类内部方法间相互调用事务不生效 ...
- JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- Spring事务管理——回滚(rollback-for)控制
探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...
- 事务特性,事务的隔离级别,并发事务可能出现的问题,spring事务 数据库锁
1.0 事务特性(ACID) Atomicity:原子性,一个事务不可以被拆分 Consistency:一致性,在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态, ...
- 本人遇到的spring事务之UnexpectedRollbackException异常解决笔记
本人最近在使用spring事务管理的过程中遇到如下异常,导致服务端抛出500给前端,让搞前端的哥们抱怨我心里着实不爽,前前后后折腾了近半个小时才得于解决,今天就做个笔记,以免日后又犯这个错误.好了,错 ...
- Spring事务管理之几种方式实现事务
1.事务认识 大家所了解的事务Transaction,它是一些列严密操作动作,要么都操作完成,要么都回滚撤销.Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring ...
- 一文带你深入浅出Spring 事务原理
Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...
- Spring事务方法上增加synchronized真的有效果吗?
此文转载,Spring事务本身是一个非常复制的问题,再加上线程并发处理就更加要主要了,由于再开发中有很多朋友会范与下文同样的错误,因分享给大家. 前言 Spring事务的一个奇怪的问题. 朋友问了我一 ...
随机推荐
- extjs 点击复选框在表格中增加相关信息行
功能效果:点击复选框在表格中自动增加相关信息行,复选框取消则表格中内容自动删除 初始效果大概是这样~~~~~ // 定义初始 存放表格数据 var gridItems = []; //省份复选框 va ...
- UVa11218 KTV
// Rujia Liu // 题意:给出n个带权集合,每个集合包含1~9中的三个整数.找出其中三个集合,使得1~9恰好各出现一次,且权和最大 // 算法:暴力n^2枚举前两个集合,直接计算出第三个集 ...
- JDBC-ODBC桥接方法连接Excel数据库的方法
通过JDBC-ODBC桥接器访问Excel电子表格 1.设置数据源 Excel数据源选择的驱动程序是Microsoft Excel Driver 2.选择表 与访问其他数据库不同的是,我们必须在电子表 ...
- C++ Code_HotKey
Code::使用HotKeyCtrl定义一个系统热键 // 关联HotKeyCtrl控件变量 m_HotKey1 BEGIN_MESSAGE_MAP(CXyzDlg, CD ...
- Mysql命令alter add:增加表的字段
alter add命令用来增加表的字段. alter add命令格式:alter table 表名 add字段 类型 其他; 例如,在表MyClass中添加了一个字段passtest,类型为int(4 ...
- 【JavaScript】关于js的一些理解
嵌套函数即作用域链:嵌套函数即闭包 函数表达式即延迟执行 匿名函数----------->实现块级作用域 call会切换到调用的对象参数环境.
- Perl小知识点之排序sort
脚本这种东西,就是要常用,否则一段时间不用就生疏了,因此决定时时记一些小知识点,一来回顾一下,二来需要的时候可以迅速获得提示. Sort by number You could now write a ...
- MySQL auto_increment实现
http://www.cnblogs.com/xpchild/p/3825309.html 运维的时候,经常遇到auto_increment的疑惑: 机器异常crash,重启后id回退的问题 性能考虑 ...
- ORCLE INNODB 博客与 innodb_lru_scan_depth
https://blogs.oracle.com/mysqlinnodb/ http://mysqllover.com/?p=485 •MySQL. MySQL 5.6.10 http://www.m ...
- Linux用户空间与内核空间(理解高端内存)
Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...