项目地址:git@github.com:witaste/transaction-annotation.git

情景一:

A external method calls a method of the target object 

外部方法调用目标对象的事务方法,异常逐层抛出,最终由a() 抛出,可以回滚。

@Service
public class FooServiceImpl implements FooService { @Autowired
private FooMapper fooMapper; @Transactional(propagation = Propagation.REQUIRED)
public void a() {
b();
} public void b() {
fooMapper.insert(new Foo("1"));
int i = 1 / 0;
fooMapper.insert(new Foo("2"));
}
}

情景二:

The target object call another method of the target object 

不能开启事务,插入了一条数据。

@Service
public class FooServiceImpl implements FooService { @Autowired
private FooMapper fooMapper; public void a() {
try {
b();
} catch (Exception e) {
System.out.println(e.getMessage());
}
} @Transactional(propagation = Propagation.REQUIRED)
public void b() {
fooMapper.insert(new Foo("1"));
int i = 1 / 0;
fooMapper.insert(new Foo("2"));
}
}

情景二解决办法:

办法1.

将b() 转移到OtServiceImpl 中即可。

办法2.

使用代理对象调用b() , 即:

((FooService) AopContext.currentProxy()).b();

需要引入jar包

        <!-- aspectj -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.7</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>

需要暴露代理:

<aop:aspectj-autoproxy expose-proxy="true"/>

修改后的类:

@Service
public class FooServiceImpl implements FooService { @Autowired
private FooMapper fooMapper; public void a() {
try{
((FooService) AopContext.currentProxy()).b();
}catch(Exception e){
System.out.println(e.getMessage());
}
} @Transactional(propagation = Propagation.REQUIRED)
public void b() {
fooMapper.insert(new Foo("1"));
int i = 1 / 0;
fooMapper.insert(new Foo("2"));
}
}

PS:其他复杂情景不做考虑

官方文档:http://docs.spring.io/spring/docs/4.2.0.RC1/spring-framework-reference/htmlsingle/#transaction-declarative-annotations

附运行日志:

情景一:

16:02:27.372 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
16:02:27.372 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:02:27.403 [main] DEBUG o.m.s.t.SpringManagedTransaction - JDBC Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver] will be managed by Spring
16:02:27.403 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:02:27.403 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Preparing: select sys_guid() from dual
16:02:27.513 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Parameters:
16:02:27.872 [main] DEBUG cn.zno.dao.FooMapper.insert - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:02:27.872 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Preparing: insert into FOO (ID, NAME) values (?, ?)
16:02:27.872 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Parameters: 220CFD8EE4A60CF3E053433210AC3DFB(String), 1(String)
16:02:27.903 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:02:27.950 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization rolling back SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:02:27.950 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]

情景二:

16:09:12.544 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
16:09:12.544 [main] DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@db15e1] was not registered for synchronization because synchronization is not active
16:09:12.622 [main] DEBUG o.m.s.t.SpringManagedTransaction - JDBC Connection [24683438, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver] will not be managed by Spring
16:09:12.622 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ooo Using Connection [24683438, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:09:12.622 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Preparing: select sys_guid() from dual
16:09:12.732 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Parameters:
16:09:12.794 [main] DEBUG cn.zno.dao.FooMapper.insert - ooo Using Connection [24683438, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:09:12.794 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Preparing: insert into FOO (ID, NAME) values (?, ?)
16:09:12.794 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Parameters: 220D15B5E3891024E053433210AC7FE0(String), 1(String)
16:09:12.841 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@db15e1]
/ by zero

情景二改:

16:12:13.466 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
16:12:13.482 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:12:13.513 [main] DEBUG o.m.s.t.SpringManagedTransaction - JDBC Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver] will be managed by Spring
16:12:13.513 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:12:13.513 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Preparing: select sys_guid() from dual
16:12:13.622 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Parameters:
16:12:13.685 [main] DEBUG cn.zno.dao.FooMapper.insert - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:12:13.685 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Preparing: insert into FOO (ID, NAME) values (?, ?)
16:12:13.685 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Parameters: 220D207E0A56111CE053433210ACAD95(String), 1(String)
16:12:13.716 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:12:13.747 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization rolling back SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:12:13.747 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
/ by zero

spring @Transactional 声明式事务的更多相关文章

  1. @Transactional、Spring的声明式事务

    传送门 一.Spring的声明式事务 需要在xml文件中配置 <!--配置事务管理器类--> <bean id="transactionManager" clas ...

  2. Spring之声明式事务

    在讲声明式事务之前,先回顾一下基本的编程式事务 编程式事务: //1.获取Connection对象 Connection conn = JDBCUtils.getConnection(); try { ...

  3. 【Spring】——声明式事务配置详解

    项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...

  4. Spring AOP声明式事务异常回滚(转)

    转:http://hi.baidu.com/iduany/item/20f8f8ed24e1dec5bbf37df7 Spring AOP声明式事务异常回滚 近日测试用例,发现这样一个现象:在业务代码 ...

  5. 使用注解实现Spring的声明式事务管理

    使用注解实现Spring的声明式事务管理,更加简单! 步骤: 1) 必须引入Aop相关的jar文件 2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类 3)在需要添加事务控制 ...

  6. Spring(四)Spring JdbcTemplate&声明式事务

    JdbcTemplate基本使用 01-JdbcTemplate基本使用-概述(了解) JdbcTemplate是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装.spr ...

  7. 保护亿万数据安全,Spring有“声明式事务”绝招

    摘要:点外卖时,你只需考虑如何拼单:选择出行时,你只用想好目的地:手机支付时,你只需要保证余额充足.但你不知道这些智能的背后,是数以亿计的强大数据的支持,这就是数据库的力量.那么庞大数据的背后一定会牵 ...

  8. spring aop 声明式事务管理

    一.声明式事务管理的概括 声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一. Spring的声明式事务顾名思义就是采用声明 ...

  9. spring的声明式事务,及redis事务。

    Redis的事务功能详解 http://ghoulich.xninja.org/2016/10/12/how-to-use-transaction-in-redis/ MULTI.EXEC.DISCA ...

随机推荐

  1. Spring 中的国际化Message的简单例子(ApplicationContext) 不跟框架集成的版本

    首先,建立一个描述message的XML文件,名为messages.xml     <?xml version="1.0" encoding="UTF-8" ...

  2. 基元线程同步构造之信号量(Semaphore)

    信号量(semaphore)不过是由内核维护的 int32变量而已,(说通俗点就是好比一个线程容器里面允许执行的线程数,0计数就是允许执行的0个线程数,1就是允许执行的1个线程数,2就是允许执行的2个 ...

  3. keras做DNN

    输入的数据集是10000行,31645列,其中前31644是特征,最后一列是标签值.训练集和测试集格式是一样的. 特征值都是0,1形式,表示有还是没有这个特征,标签值是0,1形式,2分类. impor ...

  4. Swagger+ springfox +Spring mvc

    简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集 ...

  5. SO\PR回写的数据如下

    insert into OUT_ORDER_RES ---JAVA FOR PR ) as LGORT ,'SAPRFC' as ERNAM,out_pr.due_datetime,out_pr.so ...

  6. 亲, 我们来再重申一遍"=="和"equals的区别

    今天经历的一个事情太丢脸了, 一个学弟向我请教问题, 是这样的: 一个字符串里面含有空格, 不允许使用.trim()和replace方法, 只用if和for将空格去掉, 题目很简单, 一开始我是这样写 ...

  7. Codeforces Round #533 (Div. 2)

    C: 题意: 有n个整数ai,数列a有两个神奇的性质.1.所有的整数都在[l,r]范围内.2.这n个数的和能被3整除.现在给出l和r,和个数n,问你有多少种方法构造出数列a,方案数mod1e9+7. ...

  8. 配置Maven从私服下载构件

    --------------------siwuxie095                                     配置 Maven 从私服下载构件         从 Nexus ...

  9. 带最小值操作的栈 · Min Stack

    [抄题]: 实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. [思维问题]: [一句话思 ...

  10. ubuntu 安装 google Gtest

    1.安装源代码 在ubuntu的桌面上,右键选择打开终端,在终端中输入如下命令: $ sudo apt-get install libgtest-dev 下载源码后,apt将会在目录/usr/src/ ...