spring @Transactional 声明式事务
项目地址: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:其他复杂情景不做考虑
附运行日志:
情景一:
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 声明式事务的更多相关文章
- @Transactional、Spring的声明式事务
传送门 一.Spring的声明式事务 需要在xml文件中配置 <!--配置事务管理器类--> <bean id="transactionManager" clas ...
- Spring之声明式事务
在讲声明式事务之前,先回顾一下基本的编程式事务 编程式事务: //1.获取Connection对象 Connection conn = JDBCUtils.getConnection(); try { ...
- 【Spring】——声明式事务配置详解
项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...
- Spring AOP声明式事务异常回滚(转)
转:http://hi.baidu.com/iduany/item/20f8f8ed24e1dec5bbf37df7 Spring AOP声明式事务异常回滚 近日测试用例,发现这样一个现象:在业务代码 ...
- 使用注解实现Spring的声明式事务管理
使用注解实现Spring的声明式事务管理,更加简单! 步骤: 1) 必须引入Aop相关的jar文件 2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类 3)在需要添加事务控制 ...
- Spring(四)Spring JdbcTemplate&声明式事务
JdbcTemplate基本使用 01-JdbcTemplate基本使用-概述(了解) JdbcTemplate是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装.spr ...
- 保护亿万数据安全,Spring有“声明式事务”绝招
摘要:点外卖时,你只需考虑如何拼单:选择出行时,你只用想好目的地:手机支付时,你只需要保证余额充足.但你不知道这些智能的背后,是数以亿计的强大数据的支持,这就是数据库的力量.那么庞大数据的背后一定会牵 ...
- spring aop 声明式事务管理
一.声明式事务管理的概括 声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一. Spring的声明式事务顾名思义就是采用声明 ...
- spring的声明式事务,及redis事务。
Redis的事务功能详解 http://ghoulich.xninja.org/2016/10/12/how-to-use-transaction-in-redis/ MULTI.EXEC.DISCA ...
随机推荐
- web 项目手机页面不允许缩放
https://blog.csdn.net/ljw_jiawei/article/details/80421240
- DOM0和D0M2级事件
1.DOM0级事件:on+事件类型 1.1.在html行内直接绑定, 1.2.在js中绑定 A.DOM0级事件和DOM0级事件相互之间会覆盖,比如以下代码执行后弹出jsDOM0级,js中绑定的事件 覆 ...
- statement 对象执行sql语句
statement对象执行sql语句 关于Statement.它是Java执行数据库操作的一个重要步骤,可以执行一些简单的SQL语句,从而完成对数据库的操作.它有两个子接口,分别是Prepare ...
- .Spark Streaming(上)--实时流计算Spark Streaming原理介
Spark入门实战系列--7.Spark Streaming(上)--实时流计算Spark Streaming原理介绍 http://www.cnblogs.com/shishanyuan/p/474 ...
- array numpy 模块
高级用法:http://www.jb51.net/article/87987.htm from array import * 调用 array 与 import numpy as np 调用 np. ...
- Swagger与SpringMVC整合
依赖管理 在整合之前,需要把所有使用到的依赖包全部引入.网上很多文章只是简单告诉读者引入swagger-springmvc-1.0.2.jar包,但是随后你发现这远远不够,还需要很多包,如下所示: ...
- Java HashMap,LinkedHashMap,TreeMap
Java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMapMap主要用于存储健值对,根据 ...
- Element div is not closed
报错内容:Element div is not closed 解决方法: 将代码复制到NotePad++.SubLime Text等文本编辑器中,另存为.jsp或者.html文件. 这样可以利用语法高 ...
- 64位tomcat不能配32位的JDK使用
警告: The APR based Apache Tomcat Native library failed to load. The error reported was [D:\apache-tom ...
- 乱序字符串anagrams
[抄题]: 给出一个字符串数组S,找到其中所有的乱序字符串(Anagram).如果一个字符串是乱序字符串,那么他存在一个字母集合相同,但顺序不同的字符串也在S中. 对于字符串数组 ["lin ...