[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; /** * * 这里不用 ...
随机推荐
- [Swift]LeetCode998. 最大二叉树 II | Maximum Binary Tree II
We are given the root node of a maximum tree: a tree where every node has a value greater than any o ...
- SpringBoot + SpringCloud学习踩坑实记
踩的坑: 1).springcloud框架中,依赖一直报错,很可能是没有添加springcloud的依赖,或者是依赖的版本号过低.并且springboot也有一个父依赖. 2.springcloud ...
- ECMAScript5.1的运算符、类型转换总结
一.运算符优先级 从高到低 运算符 说明 () 圆括号 . [] new(带参数列表) 字段访问.数组索引.new(带参数列表) () new(无参数列表) 函数调用,无参数列表 ++(后置递增) - ...
- RabbitMQ学习笔记(四) Routing
新的场景 在我们学习了RabbitMQ的发布与订阅之后,我们很容易就可以完成一个简单的消息群发器. 使用这个消息群发器,所有的消费者程序实例都会接收到相同的消息信息,从而实现广播的效果. 但是这种广播 ...
- Sdcard插拔、状态广播监听,Android文件系统,Android存储器相关知识总结
一 SDcard广播监听,注册,取消注册的实现 (1)根据实际需要监听的事件,添加action,并注册,一般在onCreate中添加 //在IntentFilter中选择你要监听的行为 IntentF ...
- ZooKeeper 01 - 什么是ZooKeeper + 部署ZooKeeper集群
目录 1 什么是ZooKeeper 2 ZooKeeper的功能 2.1 配置管理 2.2 命名服务 2.3 分布式锁 2.4 集群管理 3 部署ZooKeeper集群 3.1 下载并解压安装包 3. ...
- HBase Region合并分析
1.概述 HBase中表的基本单位是Region,日常在调用HBase API操作一个表时,交互的数据也会以Region的形式进行呈现.一个表可以有若干个Region,今天笔者就来和大家分享一下Reg ...
- WebClient下载文件
public void DownDile(string url) { WebClient client = new WebClient(); string URLAddress = @"ht ...
- Captcha服务(后续1)
既然标题为后续,就要放一下上一篇文章使用.Net Core 2.1开发Captcha图片验证码服务 继续挖坑 时隔7个月再次继续自己在GitHub上挖的坑 https://github.com/Puz ...
- Java开发笔记(四)Java帝国的度量衡
秦始皇统一中国之后,实行“书同文,车同轨”,把货币和各种度量衡都统一起来,从而缔造了一个秩序井然的帝国.既然统一度量衡是每个帝国都要做的事情,Java帝国也不例外,对于人生地不熟的初学者来说,只有认识 ...