首先,准备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实现类中非事务方法直接调用自身事务方法导致事务无效的原因的更多相关文章

  1. SNF快速开发平台MVC-EasyUI3.9之-WebApi和MVC-controller层接收的json字符串的取值方法和调用后台服务方法

    最近项目组很多人问我,从前台页面传到后台controller控制层或者WebApi 时如何取值和运算操作. 今天就都大家一个在框架内一个取值技巧 前台JS调用代码: 1.下面是选中一行数据后右键点击时 ...

  2. QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)

    前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法, ...

  3. 是否可以从一个static方法内部调用非static方法?

    不可以.静态成员不能调用非静态成员. 非static方法属于对象,必须创建一个对象后,才可以在通过该对象来调用static方法.而static方法调用时不需要创建对象,通过类就可以调用该方法.也就是说 ...

  4. Spring中 PROPAGATION_REQUIRED 解释 事物是在一个方法里调用其他的方法,一起成功或者一起失败,是方法之间的关系,而不是某一个方法内部的问题。而且要以抛异常的方式来表明方法的失败,以此来导致事物起作用,大家全失败。

    事务传播行为种类 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为, 它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播: 事务传播行为类型 事务传播 ...

  5. 关于srping的AOP事务管理问题,自定义切面是否导致事务控制失效

    applicationContext.xml: <!-- 方法调用时间记录 --> <bean id="methodExecuteTime" class=&quo ...

  6. JNI-Thread中start方法的调用与run方法的回调分析

    前言 在java编程中,线程Thread是我们经常使用的类.那么创建一个Thread的本质究竟是什么,本文就此问题作一个探索. 内容主要分为以下几个部分 1.JNI机制的使用 2.Thread创建线程 ...

  7. python__基础 : 多继承中方法的调用顺序 __mro__方法

    在多继承中,如果一个子类继承了两个平级的父类,而这两个父类有两个相同名字的方法,那么一般先继承谁,调用方法就调用先继承的那个父类的方法.如: class A: def test(self): prin ...

  8. Java-main方法中调用非static方法

    java的calss中,在public static void main(String[] args) { }方法中调用非static的方法:在main方法中创建该calss的对象,用对象调用非sta ...

  9. 10、一个action中处理多个方法的调用第二种方法method的方式

    在实际的项目中,经常采用现在的第二种方式在struct.xml中采用清单文件的方式 我们首先来看action package com.bjpowernode.struts2; import com.o ...

  10. 10、一个action中处理多个方法的调用第一种方法动态调用

    我们新建一个用户的action package com.weiyuan.test; import com.opensymphony.xwork2.ActionSupport; /** * * 这里不用 ...

随机推荐

  1. [Swift]LeetCode718. 最长重复子数组 | Maximum Length of Repeated Subarray

    Given two integer arrays A and B, return the maximum length of an subarray that appears in both arra ...

  2. [Swift]LeetCode865. 具有所有最深结点的最小子树 | Smallest Subtree with all the Deepest Nodes

    Given a binary tree rooted at root, the depth of each node is the shortest distance to the root. A n ...

  3. [Swift]LeetCode955. 删列造序 II | Delete Columns to Make Sorted II

    We are given an array A of N lowercase letter strings, all of the same length. Now, we may choose an ...

  4. 11.Git分支-远程跟踪分支的概念、多个远程仓库的使用

    1.远程跟踪分支的概念 远程引用是对远程仓库的引用,包括分支.标签等等. 1.可以通过 git ls-remote <remote> 来获得远程引用的完整列表  2.git remote ...

  5. Hive篇--相关概念整理一

    一.前述 hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行. 其优点是学习成本低 ...

  6. shell初识

    今天写blog才发现以前还有没写起的,我的天,我是睡着了么... 1,什么是shell? shell是unix/Linux系统的一个用充当内核与用户之间的接口的软件,它读取用户的输入命令,发送给内核让 ...

  7. springboot情操陶冶-web配置(三)

    承接前文springboot情操陶冶-web配置(二),本文将在前文的基础上分析下mvc的相关应用 MVC简单例子 直接编写一个Controller层的代码,返回格式为json package com ...

  8. 脚本检测Kafka和Zookeeper

    Java测试环境中Kafka最近总是自动停止,所有写了一个简单的脚本来监听Kafka和Zookeeper,其中Kafka监听端口为9092,Zookeeper监听端口为2181,脚本如下: #!/bi ...

  9. VisualStudio移动开发(C#、VB.NET)Smobiler开发平台——AlbumView相册控件的使用方式

    AlbumView控件 一.          样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的“Smobiler Components”拖动一个AlbumView控件到窗体界面上 修改 ...

  10. C# 添加、修改以及删除Excel迷你图表的方法

    Excel表格中的迷你图表能够直观地向我们展示出数据的变化趋势.本文将介绍C#如何实现为表格数据生成迷你图表,以及修改和删除迷你图表的方法.下面将详细讲述. 所用组件工具:Spire.XLS for ...