[spring transaction],service实现类中非事务方法直接调用自身事务方法导致事务无效的原因
首先,准备service接口,两个
public interface AccountService {
public void createAccount(Account account, int throwExpFlag) throws Exception;
public void createAccountShell(Account account, int i) throws Exception;
}
public interface RoleService {
public void createAccountShell(Account account, int i) throws Exception;
}
相关impl
@Service
public class AccountServiceImpl implements AccountService { @Resource
private AccountDAO accountDAO; @Override
@Transactional
public void createAccount(Account account, int throwExpFlag) throws Exception {
accountDAO.save(account);
RoleServiceImpl.throwExp(throwExpFlag);
} @Override
public void createAccountShell(Account account, int i) throws Exception {
this.createAccount(account, i);
} }
@Service
public class RoleServiceImpl implements RoleService { @Autowired
AccountService accountService; public static void throwExp(int throwExpFlag) throws Exception {
if (throwExpFlag == 0) {
throw new RuntimeException("<< rollback transaction >>");
} else if (throwExpFlag != 1) {
throw new Exception("<< do not rollback transaction >>");
}
} @Override
public void createAccountShell(Account account, int i) throws Exception {
accountService.createAccount(account, i);
} }
测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-dao.xml", "classpath:spring/spring-service.xml"})
public class ServiceTransactionTest extends TestCase { public static Account account; static {
account = new Account();
account.setId(779);
account.setUsername("779 USER");
account.setPassword("0123456");
} @Autowired
AccountService accountService; @Autowired
RoleService roleService; @Test
public void test_1() throws Exception {
this.accountService.createAccount(account, 0);
} @Test
public void test_2() throws Exception {
this.accountService.createAccountShell(account, 0);
} @Test
public void test_3() throws Exception {
roleService.createAccountShell(account, 0);
} }
(一)对测试类的test_1方法进行单元测试时,由于AccountServiceImpl.createAccount方法显示配置了事务(@Transactional),所以spring正常接管事务。
(二)对测试类的test_2方法进行单元测试时,AccountServiceImpl.createAccountShell方法并没有显示配置事务,但其却调用了AccountServiceImpl.createAccount方法(已配事务)。然并卵,当抛出RuntimeException时,没有rollback,说明spring没有接管事务。(猜测原因:AccountServiceImpl.createAccountShell 被显示调用时,spring是知道的,但由于AccountServiceImpl.createAccountShell没有显示配置事务,spring并没有对此进行事务的管理,在AccountServiceImpl.createAccountShell内部虽然调用了配置了事务的createAccount方法,但spring并不知道或无法确定事务上下文,所以结果是并没有因为抛出的运行时异常而进行rollback)。
(三)测试test_3,虽然RoleServiceImpl.createAccountShell同样没有配置事务,但抛出RuntimeException时,spring接管了事务并rollback。(猜测原因:虽然RoleServiceImpl.createAccountShell没有配置事务,但其内部调用另一个service实例的方法,即AccountService.createAccount时,spring对此是获知的,又因为AccountServiceImpl.createAccount显示配置了事务,所以spring接管了事务)。
(四)如果在AccountServiceImpl.createAccountShell配置了事务,那么在执行test_2时,spring是可以接管事务的。
[spring transaction],service实现类中非事务方法直接调用自身事务方法导致事务无效的原因的更多相关文章
- SNF快速开发平台MVC-EasyUI3.9之-WebApi和MVC-controller层接收的json字符串的取值方法和调用后台服务方法
最近项目组很多人问我,从前台页面传到后台controller控制层或者WebApi 时如何取值和运算操作. 今天就都大家一个在框架内一个取值技巧 前台JS调用代码: 1.下面是选中一行数据后右键点击时 ...
- QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)
前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法, ...
- 是否可以从一个static方法内部调用非static方法?
不可以.静态成员不能调用非静态成员. 非static方法属于对象,必须创建一个对象后,才可以在通过该对象来调用static方法.而static方法调用时不需要创建对象,通过类就可以调用该方法.也就是说 ...
- Spring中 PROPAGATION_REQUIRED 解释 事物是在一个方法里调用其他的方法,一起成功或者一起失败,是方法之间的关系,而不是某一个方法内部的问题。而且要以抛异常的方式来表明方法的失败,以此来导致事物起作用,大家全失败。
事务传播行为种类 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为, 它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播: 事务传播行为类型 事务传播 ...
- 关于srping的AOP事务管理问题,自定义切面是否导致事务控制失效
applicationContext.xml: <!-- 方法调用时间记录 --> <bean id="methodExecuteTime" class=&quo ...
- JNI-Thread中start方法的调用与run方法的回调分析
前言 在java编程中,线程Thread是我们经常使用的类.那么创建一个Thread的本质究竟是什么,本文就此问题作一个探索. 内容主要分为以下几个部分 1.JNI机制的使用 2.Thread创建线程 ...
- python__基础 : 多继承中方法的调用顺序 __mro__方法
在多继承中,如果一个子类继承了两个平级的父类,而这两个父类有两个相同名字的方法,那么一般先继承谁,调用方法就调用先继承的那个父类的方法.如: class A: def test(self): prin ...
- Java-main方法中调用非static方法
java的calss中,在public static void main(String[] args) { }方法中调用非static的方法:在main方法中创建该calss的对象,用对象调用非sta ...
- 10、一个action中处理多个方法的调用第二种方法method的方式
在实际的项目中,经常采用现在的第二种方式在struct.xml中采用清单文件的方式 我们首先来看action package com.bjpowernode.struts2; import com.o ...
- 10、一个action中处理多个方法的调用第一种方法动态调用
我们新建一个用户的action package com.weiyuan.test; import com.opensymphony.xwork2.ActionSupport; /** * * 这里不用 ...
随机推荐
- VIVO 手机重力传感器踩坑记录
手上的 vivo-x9 手机传感器模式下的旋转效果有误,经查发现是 Gravity sensor 返回的数据有误,和其他机型返回的数据相反的. 参考 Gravity 的说明: A three dime ...
- 两分钟搞懂UiAutomator、UiAutomator2、Bootstrap的关系
很多同学经过一段时间的学习之后都明白了Appium的基本原理,但是越学习到后面发现出现的很多陌生名词无法弄清楚其具体作用,今天这篇文章的目的就是为了让大家来弄懂三个高频名词:UiAutomator.U ...
- Python Django(WEB电商项目构建)
(坚持每一天,就是成功) Python Django Web框架,Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式,即模型M,模板T和视图V组成. 安装Pyth ...
- java中过多if-else分支语句的优化方案
利用Map优化过的的if-else分支 package com.taiping.test; import java.util.HashMap;import java.util.Map; public ...
- Python—day17时间模块、系统模块、递推遍历、序列化
一.time'''时间戳(timestamp):time.time()延迟线程的运行:time.sleep(secs)(指定时间戳下的)当前时区时间:time.localtime([secs])(指定 ...
- Python内置函数(38)——list
英文文档: class list([iterable]) Rather than being a function, list is actually a mutable sequence type, ...
- java代码之美(2)---Java8 Stream
Stream 第一次看到Stream表达式就深深把我吸引,用它可以使你的代码更加整洁而且对集合的操作效率也会大大提高,如果你还没有用到java8的Stream特性,那就说明你确实out啦. 一.概述 ...
- Android Native crash日志分析
在Android应用crash的类型中,native类型crash应该是比较难的一种了,因为大家接触的少,然后相对也要多转几道工序,所有大部分对这个都比较生疏.虽然相关文章也有很多了,但是我在刚开始学 ...
- Solr 05 - Solr Web管理界面的基本使用
目录 1 Dashboard - 仪表盘 2 Logging - 日志信息 3 CoreAdmin - Solr核心 4 Java Properties - Java参数 5 Thread Dump ...
- 总结Unity 初学者容易犯的编译与运行时错误
总结Unity 初学者容易犯的编译与运行时错误 1: Untiy 出现编译错误: NewLine In Constant 解决方法: 方法一:如果报错脚本比较少量的话,可能用记事本打开报错的脚 ...