Spring 事务传递教程_有实例
来源:互联网 发布:wps表格数据求和 编辑:程序博客网 时间:2024/05/29 11:51
通过这篇文章,你将学习到Spring框架中中事务的传递
简介
在处理Spring管理的事务时,开发人员可以以传播的方式定义事务的行为。换句话说,开发人员能够决定业务方法如何被封装在逻辑和物理事务中。来自不同Spring bean的不同方法可以在相同的事务范围或分割为多个嵌套的事务中执行。这可能导致像内部事务产生的结果如何影响外部事务的细节。我们将在下一节中看到Spring中不同的传播机制的不同行为。
本教程将仅关注事务的传播机制行为。Spring事务的其他方面的细节,你可以参考其他的教程或Spring官方文档。
本教程所使用的完整代码可以在教程的下方下载。我们将仅显示Spring中帮助大家了解事务传播机制相关部分。
完整的源代码使用Hibernate实现持久层(Spring使用Hibernate的事务示例)。
表1事务传播行为类型
事务传播行为类型
说明
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
REQUIRED行为
Spring的REQUIRED行为意味着如果在当前bean方法执行的上下文中已存在打开的事务,则使用该事务;如果没有已存在的事务,则Spring容器会创建新的事务并使用它。如果多个方法均配置为REQUIRED且调用为嵌套调用,那么它们会被划分为多个逻辑的事务,但在底层使用相同物理事务。简单来说,这意味着如果内层的方法引起了事务回滚,则外部的方法调用事务也会失败同时回滚。让我们看看一个示例:
外部Bean @Autowiredprivate TestDAO testDAO; @Autowiredprivate InnerBean innerBean;@Override@Transactional(propagation=Propagation.REQUIRED)public void testRequired(User user) { testDAO.insertUser(user); try{ innerBean.testRequired(); } catch(RuntimeException e){ // handle exception }}内部Bean@Override@Transactional(propagation=Propagation.REQUIRED)public void testRequired() { throw new RuntimeException("Rollback this transaction!");}
注意内部bean的方法使用了REQUIRED进行了注解并抛出了RuntimeException。这意味着它将于外部bean使用相同的事务,因此外部事务在提交时将失败并同样进行回滚操作。
注意:默认情况下,只有非受检异常(unchecked exception),像RuntimeException,会将事务的状态设置为回滚。如果你希望受检异常(checked exception)也可以将事务状态设置为回滚,你必须设置它们,但此内部不包含在本教程中。
注意2:当使用声明式事务时(也就是通过使用注解形式),如果在相同的bean中直接调用方法(自己调用自己的方法),@Transactional注解将被容器忽略。如果你希望启用自身方法调用的事务管理,你必须使用aspectj来配置事务,但是该内容不包含在本教程中。
REQUIRES_NEW行为
REQUIRES_NEW行为意味着容器将总会创建新的物理的事务,如果当前存在事务,把当前事务挂起。
外部 bean@Autowiredprivate TestDAO testDAO;@Autowiredprivate InnerBean innerBean; @Override@Transactional(propagation=Propagation.REQUIRED)public void testRequiresNew(User user) { testDAO.insertUser(user); try{ innerBean.testRequiresNew(); } catch(RuntimeException e){ // handle exception }} 内部 bean@Override@Transactional(propagation=Propagation.REQUIRES_NEW)public void testRequiresNew() { throw new RuntimeException("Rollback this transaction!");}
内部方法使用REQUIREDS_NEW进行注解,并抛出RuntimeException,因此它的事务会回滚但是不会影响到外部的事务。外部事务在内部事务启动时将被挂起然后在内部事务处理完毕后恢复。它们独立的进行处理因此外部的事务也会成功的提交。
NETSTED行为
NESTED行为使用相同的物理事务但是在嵌套调用时设置了保留点(savepoint),因此内部的事务可以独立于外部事务回滚而不影响外部事务。这个可能与JDBC的savepoint比较类似,因此该行为需要与Spring的JDBC管理的事务一起使用(Spring JDBC 事务例子).
MANDATORY行为
MANDATORY行为要求执行该方法时,必须有一个已存在且打开的事务。如果没有已存在的事务,容器会抛出异常。
NEVER行为
NEVER行为要求执行该方法时,不能有已存在的事务。如果事务已存在,那么容器将会抛出异常。
NOT_SUPPORTED行为
NOT_SUPPORTED行为标示在执行方法时,将忽略事务。如果已存在打开的事务,则该事务会被挂起。
SUPPORTS行为
SUPPORTS行为标示在执行方法时,如果存在事务,则在事务范围执行,如果不存在,则不以事务方式执行。
完整的笔记源码
本页尾有完整的代码下载。下面是 MySQL 建表语句:
MySQL 建表语句
CREATE TABLE USER ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, USERNAME VARCHAR (32) NOT NULL, NAME VARCHAR (64) NOT NULL, UNIQUE (USERNAME));
下载本教程源码
下载链接: spring-transaction-propagation-tutorial.zip
- Spring 事务传递教程_有实例
- Spring 事务传递教程
- Spring 事务传递机制
- Spring _事务
- Spring事务配置实例
- Spring事务传递性探讨
- spring事务详解与实例
- 基于spring事务简单实例
- Spring声明式事务教程
- JavaEE_Spring_Spring事务传播特性_实例解析
- Spring教程第四篇:Spring事务
- 配置Spring数据库事务_备忘
- spring(3)_实例helloworld
- Spring的事务和Hibernate的事务有什么区别
- spring事务详解及配置、实例
- Spring单实例、多线程安全、事务解析
- Spring事务传播特性实例解析
- Spring事务传播特性实例解析
- How to evaluate and motivate a speech
- 如何学好Android 学习指南
- UIAlertController
- Bandwidth monitoring with Neutron and Ceilometer
- 2016多校联合第二场 HDU5735 Born Slippy 解题报告
- Spring 事务传递教程_有实例
- 利用二进制位求平均值
- 捕捉C#全局异常的事件处理
- ARM内核寄存器 两种状态 7种工作模式
- nodejs连接sqlserver数据库支持事物封装-mssql模块
- var
- leetcode_c++:栈:Binary Tree Postorder Traversal(145)
- html2canvas 将代码转为图片
- 递归算Fibonacci数列并记录运行时间