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 ...
随机推荐
- c++ cout cin, 命名空间
cout<<a<<endl; cout<<a; 返回值其实就是一个输出流,(cout就是输出流) 上述语句等价于(cout<<a)<<end ...
- ant使用备忘
ant是一个脚本构建工具,可能就是持续集成里面所需要的构建工具. 如果使用eclipse,里面会自带有ant工具,不需要再安装了,创建一个build.xml(或者其他的名字都可以),使用ant来运行就 ...
- JS中数组的创建方法
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- linux 下 安装nginx及压力测试
linux 编译安装nginx,配置自启动脚本 下载nginx: wget http://nginx.org/download/nginx-1.8.0.tar.gz下载openssl : wget h ...
- python,遍历文件的方法
在做验证码识别时,识别时需要和库里的图片对比,找到最接近的那个图片,然后就行到了用与图片一致的字符命名,获取文件的名称,去将图片的名称读出来作为验证码.以下是我通过网上的资料总结的三种文件遍历的方式, ...
- android笔记:Service
服务:在后台运行,没有界面的组件. 服务生命周期如下: 两种启动方式: 1.startService(): onCreate()-->onStartCommand()-->onDestro ...
- luoguP1064 金明的预算方案 (有依赖的背包问题)
题目链接:https://www.luogu.org/problemnew/show/P1064 这是一个有依赖的背包问题,属于01背包的变式.这题还好,每个主件最多有2个附件,那么在对主件进行背包的 ...
- ubuntu 下当前网速查看
ubuntu下用ethstatus可以监控实时的网卡带宽占用.这个软件能显示当前网卡的 RX 和 TX 速率,单位是Byte 一.安装 ethstatus 软件 #sudo apt-get insta ...
- keras—多层感知器识别手写数字算法程序
#coding=utf-8 #1.数据预处理 import numpy as np #导入模块,numpy是扩展链接库 import pandas as pd import tensorflow im ...
- 前端基础之Bootstrap
1. 页面加载完之后才执行的JS代码 1. DOM方式 window.onload = function(){} 2. jQuery方式 ...