zoukankan      html  css  js  c++  java
  • spring事务概念与获取事务时事务传播行为源码分析

    一、事务状态:org.springframework.transaction.TransactionStatus

    isNewTransaction 是否是新事务

    hasSavepoint 是否有保存点

    setRollbackOnly 设置回滚

    isRollbackOnly 是否回滚

    flush 刷新

    isCompleted 是否完成

    二、传播行为

    1.传播行为分类

    类别

    简称

    无事务

    已有事务

    PROPAGATION_REQUIRED

    Required(必须-默认)

    创建一个新的事务

    使用该事务

    PROPAGATION_SUPPORTS

    Supports(支持)

    以非事务执行

    使用该事务

    PROPAGATION_MANDATORY

    Mandatory(强制)

    抛异常

    使用该事务

    PROPAGATION_REQUIRES_NEW

    requires_new(必须新的)

    创建一个新的事务

    原事务挂起,创建一个新的事务

    PROPAGATION_NOT_SUPPORTED

    not_supported(不支持)

    以非事务执行

    原事务挂起,以非事务执行

    PROPAGATION_NEVER

    Never(从不)

    以非事务执行

    抛异常

    PROPAGATION_NESTED

    Nested(嵌套)

    创建一个新事务

    在嵌套事务内执行

    2.传播行为源码分析

    (1)获取事务org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(TransactionDefinition definition)

        //---------------------------------------------------------------------
        // Implementation of PlatformTransactionManager
        //---------------------------------------------------------------------
    
        /**
         * This implementation handles propagation behavior. Delegates to
         * <code>doGetTransaction</code>, <code>isExistingTransaction</code>
         * and <code>doBegin</code>.
         * @see #doGetTransaction
         * @see #isExistingTransaction
         * @see #doBegin
         */
        public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
            Object transaction = doGetTransaction();
    
            // Cache debug flag to avoid repeated checks.
            boolean debugEnabled = logger.isDebugEnabled();
    
            if (definition == null) {
                // Use defaults if no transaction definition given.
                definition = new DefaultTransactionDefinition();
            }
         // 判断是否存在事务
            if (isExistingTransaction(transaction)) {
           // 如果有事务,根据传播行为处理
    // Existing transaction found -> check propagation behavior to find out how to behave. return handleExistingTransaction(definition, transaction, debugEnabled); }       // Check definition settings for new transaction. if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); }      // 下面是不存在事务情况下,根据传播行为处理
         // 如果配置的是mandatory强制,抛异常 
    // No existing transaction found -> check propagation behavior to find out how to proceed. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { throw new IllegalTransactionStateException( "No existing transaction found for transaction marked with propagation 'mandatory'"); }
         // 如果是required必须、requires_new必须新的和nested嵌套时,创建一个新的事物
    else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { SuspendedResourcesHolder suspendedResources = suspend(null); if (debugEnabled) { logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition); } try { boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); doBegin(transaction, definition); prepareSynchronization(status, definition); return status; } catch (RuntimeException ex) { resume(null, suspendedResources); throw ex; } catch (Error err) { resume(null, suspendedResources); throw err; } } else { // Create "empty" transaction: no actual transaction, but potentially synchronization. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null); } }

    (2)已有事务时处理org.springframework.transaction.support.AbstractPlatformTransactionManager.TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled)

        /**
         * Create a TransactionStatus for an existing transaction.
         */
        private TransactionStatus handleExistingTransaction(
                TransactionDefinition definition, Object transaction, boolean debugEnabled)
                throws TransactionException {
         // 下面是对已有事务,根据传播行为处理
        
         // 如果配置的是never从不,抛异常
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) { throw new IllegalTransactionStateException( "Existing transaction found for transaction marked with propagation 'never'"); }      // 如果配置的是not_support不支持,原事务挂起,以非事务执行 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); }      // 如果配置的是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 { boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); doBegin(transaction, definition); prepareSynchronization(status, definition); return status; } catch (RuntimeException beginEx) { resumeAfterBeginException(transaction, suspendedResources, beginEx); throw beginEx; } catch (Error beginErr) { resumeAfterBeginException(transaction, suspendedResources, beginErr); throw beginErr; } }      // 如果配置是nested嵌套,在嵌套事务中执行 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 = prepareTransactionStatus(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. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, null); doBegin(transaction, definition); prepareSynchronization(status, definition); return status; } } // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED. if (debugEnabled) { logger.debug("Participating in existing transaction"); } if (isValidateExistingTransaction()) { if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel(); if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) { Constants isoConstants = DefaultTransactionDefinition.constants; throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: " + (currentIsolationLevel != null ? isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)")); } } if (!definition.isReadOnly()) { if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is"); } } } boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null); }

    三、 Spring隔离级别:

      (1)、ISOLATION_DEFAULT:使用后端数据库默认的隔离级别

      (2)、ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

      (3)、ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

      (4)、ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生

      (5)、ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的

    部分参考:https://www.cnblogs.com/ysocean/p/7617620.html

    寻找撬动地球的支点(解决问题的方案),杠杆(Java等编程语言)已经有了。xkzhangsan
  • 相关阅读:
    把函数作为参数,调用的时候,先判断这个参数是不是存在,然后调用函数的时候加上()
    @keyframes 和animation配合使用
    让sublime text3支持Vue语法高亮显示
    vue.js中的vue-cli中各个文件简单介绍
    函数节流
    Ajax原理
    Ajax同步
    判断数据类型的方法
    闭包的用途
    vue模板编译
  • 原文地址:https://www.cnblogs.com/xkzhangsanx/p/11216102.html
Copyright © 2011-2022 走看看