项目地址: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. jenkins 修改工作目录

    修改Jenkins路径 Jenkins的默认安装路径是/var/lib/jenkins 现在由于这个根目录的磁盘太小,所以切换到/data 目录下. Jenkins目录.端口.工作目录等信息在/etc ...

  2. linux配置裸设备

    1.什么裸设备?字符设备?块设备? 裸设备:也叫裸分区(原始分区),是一种没有经过格式化,不被Unix/Linux通过文件系统来读取的特殊字符设备.它由应用程序负责对它进行读写操作.不经过文件系统的缓 ...

  3. out对象以及网上答题系统

    out对象的主要功能是向客户输出响应信息,其主要方法为“print()”,可以输出任意类型的数据,HTML标记可以作为out输出的内容. 代码: 程序截图

  4. git冲突解决方案 Intellij IDEA

    一般在团队合作开发一个项目的过程中,经常出现两个人同时修改一个文件然后都向主master提交commit,这样就会产生冲突(conflict),那么这种情况如何解决? 1 新建分支 如果项目的主分支是 ...

  5. 调用webservices报错 原因是没有导入commons-logging和commons-discovery

    Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/discovery/to ...

  6. 自定义事件 js

    // 原理如下// 创建 类型为HTMLEvents的事件 var evt = document.createEvent("HTMLEvents"); // 初始化 自定义eee ...

  7. Spring依赖注入:注解注入

    注解注入顾名思义就是通过注解来实现注入, Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Com ...

  8. phpStudy7——MySql数据库的增删查改

    1. 添加数据: //添加数据 $strsql = "insert into user_info(userId,userName,phoneNumber,userScore,dataTime ...

  9. SQL日期和时间函数

    使用这些函数可以计算日期和时间值.例如,假设您希望了解通常在一周中哪一天的销售量最高.使用 DAYOFWEEK 函数,您可以创建一个公式来标识每天的销售订单数量.再比如,假设您希望比较在过去的一年中的 ...

  10. MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause

    MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause 201 ...