`

Spring 事务处理原理

阅读更多

原文:http://hi.baidu.com/sylilzy/blog/item/e17fb98fea66b9ff503d9268.html

spring的事务处理详解:调用一个方法后的事务处理过程

spring调用一个方法后的事务处理过程:
请参照TransactionInterceptor的invoke方法:
try {
   // This is an around advice.
   // Invoke the next interceptor in the chain.
   // This will normally result in a target object being invoked.
   retVal = invocation.proceed();
}
catch (Throwable ex) {
   // target invocation exception
   doCloseTransactionAfterThrowing(txInfo, ex);
   throw ex;
}
finally {
   doFinally(txInfo);
}
doCommitTransactionAfterReturning(txInfo);
return retVal;
}

调用目标方法时没有抛出异常时会调用:
doCommitTransactionAfterReturning(txInfo);
然后直接提交事务

如果抛异常则检查是否需要回滚事务(doCloseTransactionAfterThrowing方法会根据在spring中设备的Transaction Attribute),否则提交事务.

--------------------------------------

spring的事务处理详解:调用一个方法前的事务处理过程(源代码分析)


实际上,在spring的事务中,只要该类被设置为了事务代理:

拦截器都会创建一个TransactionInfo 对象:

TransactionInfo txInfo = new TransactionInfo(txAttr, method);


而且如果只要被调用的方法设置了事务属性(txAttr),不管是什么属性都会调用:

txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));

根据该方法的事务属性(definition )的不同,this.transactionManager.getTransaction(txAttr)的返回值会有所不同(代码见AbstractPlatformTransactionManager),具体为以下几种情况:
1.当前没有事务时(即以下代码中的((HibernateTransactionObject) transaction).hasTransaction()返回false),会返回以下几种:
// Check definition settings for new transaction.
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
   throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}

// No existing transaction found -> check propagation behavior to find out how to behave.
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
   throw new IllegalTransactionStateException(
     "Transaction propagation 'mandatory' but no existing transaction found");
}
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
    definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
      definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
   if (debugEnabled) {
    logger.debug("Creating new transaction with name [" + definition.getName() + "]");
   }
   doBegin(transaction, definition);
   boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
   return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
}
else {
   // Create "empty" transaction: no actual transaction, but potentially synchronization.
   boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
   return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null);
}

2.当前有事务时
private TransactionStatus handleExistingTransaction(
   TransactionDefinition definition, Object transaction, boolean debugEnabled)
   throws TransactionException {

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
   throw new IllegalTransactionStateException(
     "Transaction propagation 'never' but existing transaction found");
}

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
   if (debugEnabled) {
    logger.debug("Suspending current transaction");
   }
   Object suspendedResources = suspend(transaction);
   boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
   return newTransactionStatus(
     definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
   if (debugEnabled) {
    logger.debug("Suspending current transaction, creating new transaction with name [" +
      definition.getName() + "]");
   }
   Object suspendedResources = suspend(transaction);
   doBegin(transaction, definition);
   boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
   return newTransactionStatus(
     definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
}

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()) {
    // Create savepoint within existing Spring-managed transaction,
    // through the SavepointManager API implemented by TransactionStatus.
    // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
    DefaultTransactionStatus status =
      newTransactionStatus(definition, transaction, false, false, debugEnabled, null);
    status.createAndHoldSavepoint();
    return status;
   }
   else {
    // Nested transaction through nested begin and commit/rollback calls.
    // Usually only for JTA: Spring synchronization might get activated here
    // in case of a pre-existing JTA transaction.
    doBegin(transaction, definition);
    boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
    return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
   }
}

最后,txInfo被绑定到当前线程上作为当前事务:

txInfo.bindToThread()

然后,调用实际的目标类的方法并捕捉异常:

try {
   // This is an around advice.
   // Invoke the next interceptor in the chain.
   // This will normally result in a target object being invoked.
   retVal = invocation.proceed();
}
catch (Throwable ex) {
   // target invocation exception
   doCloseTransactionAfterThrowing(txInfo, ex);
   throw ex;
}
finally {
   doFinally(txInfo);
}
doCommitTransactionAfterReturning(txInfo);
return retVal;
}

另外一点,TransactionInfo的newTransactionStatus调用时如果参数的不是null,TransactionInfo.hasTransaction()方法返回true;

重要提示:
在spring中创建的事务代理类并是目标类的超类,只是一个实现这目标类接口的类,该类会调用目标类的方法,所在如果一个目标类中的方法调用自身的另一个事务方法,另一个方法只是作为普通方法来调用,并不会加入事务机制
--------------------------------------------------------------------------------


spring的事务处理详解:事务创建


在配置spring的事务处理时,无论使用TransactionProxyFactoryBean,还是使用BeanNameAutoProxyCreator
spring的事务处理都是主要由TransactionInterceptor来拦截完成,此类扩展自org.aopalliance.intercept.MethodInterceptor,要查看spring的事务处理过程,首先要了解
TransactionInterceptor类的执行过程:


1.事务拦截器拦截调用方法:invoke();
2.调用TransactionAspectSupport的createTransactionIfNecessary,


createTransactionIfNecessary中:
首先创建TransactionInfo对象,然后
如果被调用的方法设置了事务属性(不管是什么属性,只要设置了),输出日志:

TransactionInterceptor 221 - Getting transaction for ...

并调用TransactionManager.getTransaction方法,

如果被调用的方法设置未设备事务,输出:Don't need to create transaction for ...

调用返回后然后将事务绑定到当前线程.createTransactionIfNecessary方法返回.

3.调用目标类的方法,并依次完成其它拦截器的调用
4.如果在上一步操作中有异常抛出,则会处理异常,处理过程:根据配置决定是提交还是回滚事务
5.如无异常,调用doFinally()将上一个事务(旧事务)设置为当前事务
4.调用doCommitTransactionAfterReturning提交事务,此为最重要的一步,与事务相关的操作在此实际生效.

调用TransactionManager.getTransaction过程 :
1.调用doGetTransaction()查找事务(此对象并不代表一个事务已经存在),返回的对象中包含事务的相关信息:如事务是否开始等.此对象将在以后作为doBegin and doCommit等方法的参数.

2.输出日志:
Using transaction object...
如:
HibernateTransactionManager 254 - Using transaction object...

3.调用isExistingTransaction(...)检查事务是否存在(是否已经开始一个事务),此方法为abstract方法,需要concreate类来实现,例如hibernate

4.如果isExistingTransaction为true,
如果是PROPAGATION_NEVER,则抛异常
PROPAGATION_NOT_SUPPORTED,则suspend当前事务并返回
PROPAGATION_REQUIRES_NEW,则suspend后创建一个新事务,
其它则
输出日志:"Participating in existing transaction"
然后
处理完后返回一个TransactionStatus对象,包含是否为新transaction,是否为新的newSynchronization,suspendedResources等,getTransaction()同时也返回

5.如果isExistingTransaction为false
检查超时是否小于默认时间,如果是则抛异常
如果当前方法的事务属性为PROPAGATION_MANDATORY,则抛异常,否则
如果当前方法的事务属性为PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED
输出日志:"Creating new transaction with name ..."
调用doBegin(...)创建并开始一个事务,然后返回
否则返回的return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null);

分享到:
评论

相关推荐

    Spring事务处理原理步骤详解

    Spring事务处理原理步骤详解 Spring事务处理原理步骤详解是指在Spring框架中实现事务处理的整个过程,它涉及到事务处理的实现、事务处理原理和事务管理器的配置等几个方面。下面是Spring事务处理原理步骤详解的知识...

    Spring事务原理、Spring事务配置的五种方式

    Spring事务原理和配置 Spring事务原理是指Spring框架中的一种机制,用于管理事务,并提供了多种配置方式。事务是指一系列的操作,作为一个整体执行,如果其中某个操作失败,整个事务将回滚。Spring事务原理围绕着两...

    Spring事务处理-ThreadLocal的使用

    Spring事务处理是其核心特性之一,确保了数据的一致性和完整性。本篇文章将聚焦于Spring事务处理中ThreadLocal的使用,以及如何通过源码理解和应用这个工具。 首先,了解Spring事务管理的基本概念。在多线程环境中...

    Spring事务传播原理及数据库事务操作原理.rar

    本资料主要探讨了Spring事务的传播原理以及数据库事务的操作原理,这对于理解和使用Spring框架进行事务处理至关重要。 首先,让我们深入理解Spring事务的传播行为。在Spring中,事务的传播行为是指在一个事务方法被...

    Spring事务管理失效原因汇总

    总结来说,Spring事务管理失效的原因是多方面的,涵盖从代理模式原理到AOP的实现细节,再到异常处理机制,以及事务传播和隔离级别的配置等多个层面。开发者需要深入理解Spring框架的内部机制,才能在实际开发中有效...

    Spring事务管理Demo

    在Spring框架中,事务管理是核心特性之一,它允许开发者以声明式或编程式的方式处理应用中的事务。Spring事务管理的目的是确保数据的一致性和完整性,...这样可以帮助你更好地理解Spring事务管理的工作原理和实际应用。

    02-01-10-Spring事务传播原理及数据库事务操作原理1

    在本课程中,我们将深入探讨Spring事务传播原理和数据库事务操作的基本概念,这对于有Spring开发经验的人员来说,是进一步深化事务控制理解的关键。我们还将触及分布式事务的初步知识,帮助开发者更好地掌握基于...

    springIoc实现原理

    **Spring Ioc 实现原理详解** Spring Ioc(Inversion of Control,控制反转)是Spring框架的核心特性之一,它改变了传统应用程序中对象的创建和管理方式。在传统的软件设计中,对象的创建和依赖关系的维护通常由...

    Spring事务管理的jar包

    本篇将深入探讨Spring事务管理的核心概念、工作原理以及如何使用`spring-tx-3.2.0.RELEASE.jar`这个jar包。 首先,我们需要理解什么是事务。在数据库系统中,事务是一组操作,这些操作被视为一个整体,要么全部完成...

    Spring 事务简单完整例子

    本文将深入探讨在Spring框架中如何管理事务,以“Spring 事务简单完整例子”为出发点,结合标签“spring,事务,jdbc事务”,我们将详细解释Spring事务管理的原理和实践。 首先,Spring提供了两种事务管理方式:编程...

    深入理解Spring事务原理

    本文将深入探讨Spring事务原理,包括事务的基本概念、Spring事务的传播属性、数据库隔离级别以及事务的嵌套。 首先,事务的基本原理是基于数据库对事务的支持。在纯JDBC操作中,我们需要手动获取连接、开启和关闭...

    实验 spring 声明事务

    Spring 提供了声明式事务管理,允许开发者在不编写事务管理代码的情况下实现事务控制,极大地简化了事务处理。 实验环境主要包括 Eclipse 或 MyEclipse 开发工具,以及 Spring 4.0 及以上版本,JDK 1.7 及以上版本...

    spring 事务管理的理解

    Spring 框架是Java开发中...理解并熟练掌握Spring事务管理,对于提升应用程序的稳定性和可靠性至关重要。在实际开发中,结合声明式事务管理、事务传播行为、隔离级别和回滚规则,可以有效地确保数据的完整性和一致性。

    spring 事务基于注解模式

    Spring事务管理分为编程式和声明式两种。编程式事务管理通过编程的方式(如使用`TransactionTemplate`或直接调用`PlatformTransactionManager`)来控制事务的开始、提交、回滚等操作。而声明式事务管理则是在配置...

    Spring技术内幕:深入解析Spring架构与设计原理.pdf

    3. 事务处理:Spring提供了事务处理的功能,可以实现事务的管理和控制。 4. 分布式计算:Spring提供了分布式计算的功能,可以实现分布式应用程序的开发。 Spring与云计算 Spring与云计算的结合可以提供一个高可靠...

    深入理解spring的事务管理机制

    Spring框架的事务管理机制是在Java开发环境中非常重要的一个组成部分,它能够帮助开发者简化事务处理的复杂度,提高应用程序的一致性和可靠性。Spring事务管理的核心是基于AOP(面向切面编程)来实现的。 **Spring...

    Spring Data JPA系列4——Spring声明式事务处理与多数据源支持.doc

    下面,我们将探讨这些问题,并了解 Spring 声明式事务处理机制的实现原理和多数据源支持机制。 一、事务处理机制 事务处理机制是用于确保数据库操作的一致性和可靠性的机制。它可以确保多个操作作为一个单元来执行...

    Spring事务处理流程和原理详解

    本篇文章将深入探讨Spring事务处理的流程和原理。 一、事务理论学习 事务是数据库操作的基本单位,它封装了一组数据库操作,要么全部执行,要么全部回滚。事务具有四大特性,即ACID(原子性Atomicity、一致性...

    Hibernate、Spring和Struts工作原理及使用理由

    【标题】:“Hibernate、Spring和Struts工作原理及使用理由” 【内容】: Hibernate是一个流行的Java持久化框架,它的核心工作原理主要包括以下步骤: 1. **读取并解析配置文件**:Hibernate通过读取hibernate....

    Spring技术内幕:深入解析Spring架构与设计原理(第2版) .pdf

    - **反转控制**:Spring通过IoC容器来管理对象生命周期,开发者无需关心对象的创建和销毁过程,而是将其交给Spring容器处理。 - **代理模式**:在Spring AOP中,代理模式被广泛应用于实现横切关注点,例如通过动态...

Global site tag (gtag.js) - Google Analytics