本篇主要讨论下面几点获取【下载地址】  :

一: 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, 代码如下

  1. public void methodA() {
  2. try {
  3. methodB();
  4. } catch(Exception e) {
  5. process();
  6. }
  7. otherOperation;
  8. }
    假设MethodB抛出异常,则Consumer调用MethodA会发生怎样的情形?

发现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的异常了,但是感觉这个场景不能完全反应初回滚的事务是否可以重复回滚。代码如下:

  1. public void methodA() {
  2. methodB();
  3. otherOperation;
  4. }

e) 还有什么场景可以模拟回滚的事务是否可以再回滚呢?看,代码如下:

  1. public void methodA() {
  2. try {
  3. methodB();
  4. } catch(Exception e) {
  5. process();
  6. }
  7. try {
  8. methodB();
  9. } catch(Exception e) {
  10. process();
  11. }
  12. System.out.println("**************");
  13. otherOperation;
  14. }

第一个MethodB已经回滚了共享的事务,第二个MethodB同样会抛出异常回滚共享的事务,如果执行了后面的System.out,则说明事务可以多次回滚。测试发现打印出来了后面的SysOut的内容,所以猜测可能是这样回滚事务的时候如果发现事务已经回滚,则直接跳过。

Spring事务传递性探讨的更多相关文章

  1. Spring事务控制和传递性理解

    1.在同一类方法间相互调用,如果调用方无事务控制,被调用方有事务控制,则被调用方也无事务 原因:外部经过spring容器调用service的方法事务才生效,service类内部方法间相互调用事务不生效 ...

  2. JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

  3. (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

  4. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  5. 事务特性,事务的隔离级别,并发事务可能出现的问题,spring事务 数据库锁

    1.0 事务特性(ACID) Atomicity:原子性,一个事务不可以被拆分 Consistency:一致性,在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态, ...

  6. 本人遇到的spring事务之UnexpectedRollbackException异常解决笔记

    本人最近在使用spring事务管理的过程中遇到如下异常,导致服务端抛出500给前端,让搞前端的哥们抱怨我心里着实不爽,前前后后折腾了近半个小时才得于解决,今天就做个笔记,以免日后又犯这个错误.好了,错 ...

  7. Spring事务管理之几种方式实现事务

    1.事务认识 大家所了解的事务Transaction,它是一些列严密操作动作,要么都操作完成,要么都回滚撤销.Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring ...

  8. 一文带你深入浅出Spring 事务原理

    Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...

  9. Spring事务方法上增加synchronized真的有效果吗?

    此文转载,Spring事务本身是一个非常复制的问题,再加上线程并发处理就更加要主要了,由于再开发中有很多朋友会范与下文同样的错误,因分享给大家. 前言 Spring事务的一个奇怪的问题. 朋友问了我一 ...

随机推荐

  1. 集成iscroll 下拉加载更多 jquery插件

    一个插件总是经过了数月的沉淀,不断的改进而成的.最初只是为了做个向下滚动,自动加载的插件.随着需求和功能的改进,才有了今天的这个稍算完整的插件. 一.插件主功能: 1.下拉加载 2.页面滚动到底部自动 ...

  2. C# 反射 通过类名创建类实例

    “反射”其实就是利用程序集的元数据信息. 反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间. 1.假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型): ...

  3. 学习理论之正则化(Regularization)与模型选择

    一.引言 对于一个学习问题,可以假设很多不同的模型,我们要做的是根据某一标准选出最好的模型.例如,在多项式回归中,对于我们的假设模型,我们最要紧的是决定 k 到底取多少合适,能不能有一种方法可以自动选 ...

  4. Codeforces Educational Codeforces Round 5 C. The Labyrinth 带权并查集

    C. The Labyrinth 题目连接: http://www.codeforces.com/contest/616/problem/C Description You are given a r ...

  5. Linux文件时间属性

    Linux文件时间属性                                                                                         ...

  6. A. Fox and Box Accumulation

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  7. Java final修饰形参

    转自:http://java.chinaitlab.com/base/836044.html public class BB{ public int i; } public class PP{ pub ...

  8. boa安装

    Boa 下载地址:http://www.boa.org/boa-0.94.13.tar.gz 1.解压生成Makefile tar xzf boa-0.94.13.tar.gz #解压 cd boa- ...

  9. 生成html的几种方案

    方案1: ///   <summary > ///   传入URL返回网页的html代码 ///   </summary > ///   <param   name=&q ...

  10. crm2011创建货币Money类型的字段

    using System;     using Microsoft.Xrm.Sdk;     using Microsoft.Xrm.Sdk.Messages;     using Microsoft ...