TransactionDefinition——事务定义

定义事务属性,包括传播级别、隔离级别、名称、超时、只读等

TransactionStatus——事务状态

事务状态,包含事务对象(jdbc为DataSourceTransactionObject),是否新事务、是否新同步对象、是否只读、是否回滚、是否完成、事务中断对象(SuspendedResourcesHolder实现事务中断,保存中断事务的信息)、保存点对象(jdbc为Savepoint,实现嵌套事务)

DataSourceTransactionObject——事务对象

jdbc中事务对象。

持有一个ConnectionHolder对象,而ConnectionHolder持有Connection对象。

SuspendedResourcesHolder——中断事务对象

用于实现事务挂起,持有一个中断事务suspendedResources(jdbc为ConnectionHolder),中断同步对象集合suspendedSynchronizations。

SavePoint——保存点

保存点用于实现嵌套事务,只有jdbc才有

TransactionManger——事务管理器

AbstractPlatformTransactionManager:实现事务的获取、提交、回滚等主要逻辑

传播级别——Propagation

  1. PROPAGATION_REQUIRED:支持当前事务,没有事务开启事务
  2. PROPAGATION_SUPPORTS:支持当前事务,没有事务非事务运行
  3. PROPAGATION_MANDATORY:支持当前事务,没有事务报错
  4. PROPAGATION_REQUIRES_NEW:有事务挂起事务,新建事务
  5. PROPAGATION_NOT_SUPPORTED:有事务挂起事务,非事务执行
  6. PROPAGATION_NEVER:有事务报错
  7. 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的更多相关文章

  1. spring tx:advice 和 aop:config 配置事务

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  2. Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。

    借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...

  3. Spring <tx:annotation-driven>注解 JDK动态代理和CGLIB动态代理 区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

  4. [转]spring tx:advice 和 aop:config 配置事务

      <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www. ...

  5. 学习Spring5必知必会(7)~Spring tx

    一.spring的事务管理 1.引出事务的经典例子:银行转账发生异常 ✿ 解决:把转出钱和转入钱的业务放到同一个事务空间. ■ 分析转账过程流程: ① 首先,获取 DataSource 对象: ② 其 ...

  6. spring tx——@EnableTransactionManagement

    @EnableTransactionManagement import了TransactionManagementConfigurationSelector,而TransactionManagemen ...

  7. spring tx:advice事务配置

    http://blog.csdn.net/bao19901210/article/details/17226439 http://blog.csdn.net/rong_wz/article/detai ...

  8. 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 ...

  9. Spring 事务管理tx,aop

    spring tx:advice事务配置 2016年12月21日 17:27:22 阅读数:7629 http://www.cnblogs.com/rushoooooo/archive/2011/08 ...

随机推荐

  1. elk2

    如果使用codec->json进行解码,表示输入到logstast中的input数据必须是json的格式,否则会解码失败 java中一句代码异常会抛出多条的堆栈日志,我们可以使用上面的mutil ...

  2. Java解析apk、ipa图标,包名,应用名称,版本号

    参看:http://blog.csdn.net/moyanxuan_1993_2_24/article/details/53612001

  3. android 6.0 以上在doze模式精确定时

    public static void start12hAlarm() { int seconds = TIMERLENGTH; ECMLog.i_ecms(CLASS_TAG, " star ...

  4. 关于对Entity Framework 3.1的理解与总结

    Entity Framework Core 是一个ORM,所谓ORM也是ef的一个框架之一吧,简单的说就是把C#一个类,映射到数据库的一个表,把类里面的属性映射到表中的字段.然后Entity Fram ...

  5. 入门大数据---Flume的搭建

    一.下载并解压到指定目录 崇尚授人以渔的思想,我说给大家怎么下载就行了,就不直接放连接了,大家可以直接输入官网地址 http://flume.apache.org ,一般在官网的上方或者左边都会有Do ...

  6. 物联网SIM卡和SIM卡,真的不是一回事

    [摘要]在物联网解决方案中,设备移动上网也需要使用SIM卡.那么,SIM卡是什么?各种SIM卡有什么区别?物联网SIM卡如何选择?本文将为您答疑解惑. 通信进化史 过去几百年间,通信技术经历了天变地异 ...

  7. AJAX 调用WebService 、WebApi 增删改查(笔记)

    经过大半天努力,终于完成增删改查了!心情有点小激动!!对于初学者的我来说,一路上都是迷茫,坑!!虽说网上有资料,可动手起来却不易(初学者的我).(苦逼啊!) WebService 页面: /// &l ...

  8. Java 线程基础,从这篇开始

    线程作为操作系统中最少调度单位,在当前系统的运行环境中,一般都拥有多核处理器,为了更好的充分利用 CPU,掌握其正确使用方式,能更高效的使程序运行.同时,在 Java 面试中,也是极其重要的一个模块. ...

  9. 抓包工具-Charles基础使用

    正在整理,等待编辑过后更新....... 竟然字少不能发不出去 那..... 现..... 在..... 够..... 了..... 吗?????? 不..... 够..... 我..... 在... ...

  10. Nginx 从入门到放弃(二)

    学习完了nginx的基本知识后,我们来了解下nginx的虚拟主机. 说到虚拟主机,那就得说一说虚拟主机的三种方式了 基于端口的虚拟主机 基于域名的虚拟主机 基于ip的虚拟主机 基于端口实现虚拟主机 只 ...