spring tx——TransactionManger
TransactionDefinition——事务定义
定义事务属性,包括传播级别、隔离级别、名称、超时、只读等
TransactionStatus——事务状态
事务状态,包含事务对象(jdbc为DataSourceTransactionObject),是否新事务、是否新同步对象、是否只读、是否回滚、是否完成、事务中断对象(SuspendedResourcesHolder实现事务中断,保存中断事务的信息)、保存点对象(jdbc为Savepoint,实现嵌套事务)
DataSourceTransactionObject——事务对象
jdbc中事务对象。
持有一个ConnectionHolder对象,而ConnectionHolder持有Connection对象。
SuspendedResourcesHolder——中断事务对象
用于实现事务挂起,持有一个中断事务suspendedResources(jdbc为ConnectionHolder),中断同步对象集合suspendedSynchronizations。
SavePoint——保存点
保存点用于实现嵌套事务,只有jdbc才有
TransactionManger——事务管理器
AbstractPlatformTransactionManager:实现事务的获取、提交、回滚等主要逻辑
传播级别——Propagation
- PROPAGATION_REQUIRED:支持当前事务,没有事务开启事务
- PROPAGATION_SUPPORTS:支持当前事务,没有事务非事务运行
- PROPAGATION_MANDATORY:支持当前事务,没有事务报错
- PROPAGATION_REQUIRES_NEW:有事务挂起事务,新建事务
- PROPAGATION_NOT_SUPPORTED:有事务挂起事务,非事务执行
- PROPAGATION_NEVER:有事务报错
- PROPAGATION_NESTED:嵌套事务,外层事务回滚,内层也回滚
getTransaction——获取事务
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
//1.封装transaction对象并获取当前事务的ConnectionHolder
Object transaction = doGetTransaction();
//2.当前存在事务,根据事务传播级别处理
if (isExistingTransaction(transaction)) {
return handleExistingTransaction(def, transaction, debugEnabled);
}
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}
//3.当前不存在事务,根据不同事务传播级别处理
//3.1. 如果传播级别是PROPAGATION_MANDATORY,不存在事务报错
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
//3.2. 如果传播级别是PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
//3.2.1. 中断事务同步管理器中注册的同步对象,封装中断事务对象
SuspendedResourcesHolder suspendedResources = suspend(null);
try {
//3.2.2. 开启新事务
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
//3.2.3. 开启新事务失败,重启中断事务对象中的同步对象
resume(null, suspendedResources);
throw ex;
}
}
//3.3. 其他传播级别,以非事务执行代码,但还是封装TransactionStatus返回
else {
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
//传播级别为PROPAGATION_NEVER抛错异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
//传播级别为PROPAGATION_NOT_SUPPORTED,中断当前事务,以非事务执行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
//传播级别为PROPAGATION_REQUIRES_NEW,中断当前事务,开启新事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
//传播级别为PROPAGATION_NESTED,jdbc处理为在当前事务上创建一个保存点
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (debugEnabled) {
logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
}
if (useSavepointForNestedTransaction()) {
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
else {
// JTA事务的处理
return startTransaction(definition, transaction, debugEnabled, null);
}
}
// 传播级别为PROPAGATION_SUPPORTS、PROPAGATION_REQUIRED以当前事务执行
//省略代码。。。
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
commit——提交事务
public final void commit(TransactionStatus status) throws TransactionException {
//1.TransactionStatus设置了回滚,执行回滚操作
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
processRollback(defStatus, false);
return;
}
//2.TransactionStatus的ConnectionHolder设置了回滚,执行回滚操作
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
processRollback(defStatus, true);
return;
}
//3.执行提交操作
processCommit(defStatus);
}
processCommit方法:
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
boolean unexpectedRollback = false;
prepareForCommit(status);
//触发TransactionSynchronization的beforeCommit和beforeCompletion
triggerBeforeCommit(status);
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
//有保存点,即嵌套事务,释放保存点
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
unexpectedRollback = status.isGlobalRollbackOnly();
status.releaseHeldSavepoint();
}
//如果是事务最外层,提交事务
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
unexpectedRollback = status.isGlobalRollbackOnly();
doCommit(status);
}
//默认为false
else if (isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = status.isGlobalRollbackOnly();
}
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
//触发TransactionSynchronization的afterCompletion
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
// can only be caused by doCommit
//默认为false
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
//触发TransactionSynchronization的afterCompletion
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException | Error ex) {
//是否触发过TransactionSynchronization的beforeCompletion
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
//回滚事务
doRollbackOnCommitException(status, ex);
throw ex;
}
//触发TransactionSynchronization的afterCommit和afterCompletion
try {
triggerAfterCommit(status);
}
finally {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}
}
finally {
//有中断事务恢复中断事务,没有重置TransactionSynchronizationManager
cleanupAfterCompletion(status);
}
}
rollback——回滚事务
public final void rollback(TransactionStatus status) throws TransactionException {
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
processRollback(defStatus, false);
}
processRollback方法:
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
boolean unexpectedRollback = unexpected;
try {
//触发TransactionSynchronization的beforeCompletion
triggerBeforeCompletion(status);
//有保存点,即嵌套事务,回滚到保存点
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
status.rollbackToHeldSavepoint();
}
//如果是事务最外层,回滚事务
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
doRollback(status);
}
else {
// 如果事务标记为回滚,将ConnectionHolder标记为回滚
if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
doSetRollbackOnly(status);
}
}
// Unexpected rollback only matters here if we're asked to fail early
if (!isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = false;
}
}
}
catch (RuntimeException | Error ex) {
//触发TransactionSynchronization的afterCompletion
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
//触发TransactionSynchronization的afterCompletion
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
// Raise UnexpectedRollbackException if we had a global rollback-only marker
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
}
finally {
//有中断事务恢复中断事务,没有重置TransactionSynchronizationManager
cleanupAfterCompletion(status);
}
}
spring tx——TransactionManger的更多相关文章
- spring tx:advice 和 aop:config 配置事务
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。
借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...
- Spring <tx:annotation-driven>注解 JDK动态代理和CGLIB动态代理 区别。
基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...
- [转]spring tx:advice 和 aop:config 配置事务
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www. ...
- 学习Spring5必知必会(7)~Spring tx
一.spring的事务管理 1.引出事务的经典例子:银行转账发生异常 ✿ 解决:把转出钱和转入钱的业务放到同一个事务空间. ■ 分析转账过程流程: ① 首先,获取 DataSource 对象: ② 其 ...
- spring tx——@EnableTransactionManagement
@EnableTransactionManagement import了TransactionManagementConfigurationSelector,而TransactionManagemen ...
- spring tx:advice事务配置
http://blog.csdn.net/bao19901210/article/details/17226439 http://blog.csdn.net/rong_wz/article/detai ...
- Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx]
ERROR - Context initialization failed org.springframework.beans.factory.parsing.BeanDefinitionParsin ...
- Spring 事务管理tx,aop
spring tx:advice事务配置 2016年12月21日 17:27:22 阅读数:7629 http://www.cnblogs.com/rushoooooo/archive/2011/08 ...
随机推荐
- 数据库char varchar nchar nvarchar,编码Unicode,UTF8,GBK等,Sql语句中文前为什么加N(一次线上数据存储乱码排查)
背景 公司有一个数据处理线,上面的数据经过不同环境处理,然后上线到正式库.其中一个环节需要将数据进行处理然后导入到另外一个库(Sql Server).这个处理的程序是老大用python写的,处理完后进 ...
- Python3-pymysql模块-数据库操作之MySQL
博客转载 http://www.cnblogs.com/alex3714/articles/5950372.html 代码示例 import pymysql conn = None cursor = ...
- Day11-微信小程序实战-交友小程序-附近的人(地图的形式)及位置获取
回顾:在下面的tabbar中,我们已经实现了首页 消息 我的,就剩下”附近“页面了 ”附近“的页面主要是用地图来进行展示的(可以显示我的位置,也可以显示周围附近的人的位置) (在地图里面点击它的头像的 ...
- 深入浅出腾讯BERT推理模型--TurboTransformers
Overview TurboTransformers是腾讯最近开源的BERT推理模型,它的特点就是一个字,快.本人用BERT(huggingface/transformers)在V100上做了测试,测 ...
- JDK8--06:Stream流
一.描述 Stream流提供了筛选与切片.映射.排序.匹配与查找.归约.收集等功能 筛选与切片: filter:接收lambda,从流中排除某些元素 limit(n):截断流,使其元素不超过n ski ...
- Nginx详细介绍
1.Nginx是什么? Nginx就是反向代理服务器. 首先我们先来看看什么是代理服务器,代理服务器一般是指局域网内部的机器通过代理服务发送请求到互联网上的服务器,代理服务器一般作用于客户端.比如Go ...
- Python之浅谈多态和封装
目录 组合 什么是组合 为什么使用组合 多态和多态性 多态 什么是多态? 多态性 好处 多态性 什么是多态性 封装 封装是什么意思? 隐藏 如何用代码实现隐藏 python 实际上是可以访问隐藏属性的 ...
- Java源码详解系列(十)--全面分析mybatis的使用、源码和代码生成器(总计5篇博客)
简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository ...
- c语言学习笔记第四章——字符串和格式化输入、输出
B站有视频演示 本章学习printf函数的输入输出,字符串的定义与实用. 字符串 字符串(character string)是一个或多个字符的序列,如下所示: "Zing went the ...
- 华山论剑(没有上司的舞会)——树形dp
华山论剑(没有上司的舞会) 题目描述 一日,小策如往常一般打开了自己的传奇,刚上线不久,就收到了帮主的私信.原来帮派里要召开一次武功比拼,让他来邀请各帮派人员,因为有些侠客还是萌新,所以需要小策挨个选 ...