最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring事務(wù)處理原理步驟詳解

 更新時間:2020年03月24日 09:02:50   作者:天際星痕  
這篇文章主要介紹了Spring事務(wù)處理原理步驟詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

1、事務(wù)處理實(shí)現(xiàn)

實(shí)現(xiàn)步驟:

* 聲明式事務(wù):
*
* 環(huán)境搭建:
* 1、導(dǎo)入相關(guān)依賴
* 數(shù)據(jù)源、數(shù)據(jù)庫驅(qū)動、Spring-jdbc模塊
* 2、配置數(shù)據(jù)源、JdbcTemplate(Spring提供的簡化數(shù)據(jù)庫操作的工具)操作數(shù)據(jù)
* 3、給方法上標(biāo)注 @Transactional 表示當(dāng)前方法是一個事務(wù)方法;
* 4、 @EnableTransactionManagement 開啟基于注解的事務(wù)管理功能;
* @EnableXXX
* 5、配置事務(wù)管理器來控制事務(wù);
* @Bean
* public PlatformTransactionManager transactionManager()

代碼實(shí)現(xiàn):

@EnableTransactionManagement
@ComponentScan("com.atguigu.tx")
@Configuration
public class TxConfig {
   
  //數(shù)據(jù)源
  @Bean
  public DataSource dataSource() throws Exception{
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setUser("root");
    dataSource.setPassword("123456");
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
    return dataSource;
  }
   
  @Bean
  public JdbcTemplate jdbcTemplate() throws Exception{
    //Spring對@Configuration類會特殊處理;給容器中加組件的方法,多次調(diào)用都只是從容器中找組件
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
    return jdbcTemplate;
  }
   
  //注冊事務(wù)管理器在容器中
  @Bean
  public PlatformTransactionManager transactionManager() throws Exception{
    return new DataSourceTransactionManager(dataSource());
  }
} 

2、事務(wù)處理原理

原理分析:

* 原理:
* 1)、@EnableTransactionManagement
* 利用TransactionManagementConfigurationSelector給容器中會導(dǎo)入組件
* 導(dǎo)入兩個組件
* AutoProxyRegistrar
* ProxyTransactionManagementConfiguration
* 2)、AutoProxyRegistrar:
* 給容器中注冊一個 InfrastructureAdvisorAutoProxyCreator 組件;
* InfrastructureAdvisorAutoProxyCreator:?
* 利用后置處理器機(jī)制在對象創(chuàng)建以后,包裝對象,返回一個代理對象(增強(qiáng)器),代理對象執(zhí)行方法利用攔截器鏈進(jìn)行調(diào)用;
*
* 3)、ProxyTransactionManagementConfiguration 做了什么?
* 1、給容器中注冊事務(wù)增強(qiáng)器;
* 1)、事務(wù)增強(qiáng)器要用事務(wù)注解的信息,AnnotationTransactionAttributeSource解析事務(wù)注解
* 2)、事務(wù)攔截器:
* TransactionInterceptor;保存了事務(wù)屬性信息,事務(wù)管理器;
* 他是一個 MethodInterceptor;
* 在目標(biāo)方法執(zhí)行的時候;
* 執(zhí)行攔截器鏈;
* 事務(wù)攔截器:
* 1)、先獲取事務(wù)相關(guān)的屬性
* 2)、再獲取PlatformTransactionManager,如果事先沒有添加指定任何transactionmanger
* 最終會從容器中按照類型獲取一個PlatformTransactionManager;
* 3)、執(zhí)行目標(biāo)方法
* 如果異常,獲取到事務(wù)管理器,利用事務(wù)管理回滾操作;
* 如果正常,利用事務(wù)管理器,提交事務(wù)
*
*/

核心代碼

1、EnableTransactionManagement注解,注入TransactionManagementConfigurationSelector類

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

2、TransactionManagementConfigurationSelector類,最終會導(dǎo)入AutoProxyRegistrar.class和ProxyTransactionManagementConfiguration.class兩個組件。

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
 
  /**
   * Returns {@link ProxyTransactionManagementConfiguration} or
   * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
   * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
   * respectively.
   */
  @Override
  protected String[] selectImports(AdviceMode adviceMode) {
    switch (adviceMode) {
      case PROXY:
        return new String[] {AutoProxyRegistrar.class.getName(),
            ProxyTransactionManagementConfiguration.class.getName()};
      case ASPECTJ:
        return new String[] {determineTransactionAspectClass()};
      default:
        return null;
    }
  }
 
  private String determineTransactionAspectClass() {
    return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
        TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
        TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
  }
 
}

3、AutoProxyRegistrar類的作用為:

  給容器中注冊一個 InfrastructureAdvisorAutoProxyCreator 組件;

  最終的目的是:利用后置處理器機(jī)制在對象創(chuàng)建以后,包裝對象,返回一個代理對象(增強(qiáng)器),代理對象執(zhí)行方法利用攔截器鏈進(jìn)行調(diào)用;

@Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    boolean candidateFound = false;
    Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
    for (String annType : annTypes) {
      AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
      if (candidate == null) {
        continue;
      }
      Object mode = candidate.get("mode");
      Object proxyTargetClass = candidate.get("proxyTargetClass");
      if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
          Boolean.class == proxyTargetClass.getClass()) {
        candidateFound = true;
        if (mode == AdviceMode.PROXY) {
          AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
          if ((Boolean) proxyTargetClass) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            return;
          }
        }
      }
    }
    if (!candidateFound && logger.isInfoEnabled()) {
      String name = getClass().getSimpleName();
      logger.info(String.format("%s was imported but no annotations were found " +
          "having both 'mode' and 'proxyTargetClass' attributes of type " +
          "AdviceMode and boolean respectively. This means that auto proxy " +
          "creator registration and configuration may not have occurred as " +
          "intended, and components may not be proxied as expected. Check to " +
          "ensure that %s has been @Import'ed on the same class where these " +
          "annotations are declared; otherwise remove the import of %s " +
          "altogether.", name, name, name));
    }
  }

InfrastructureAdvisorAutoProxyCreator類的作用與AnnotationAwareAspectJAutoProxyCreator類的作用類似。

@SuppressWarnings("serial")
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

4、ProxyTransactionManagementConfiguration類

代理事務(wù)管理配置類

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
 
  @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
    BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
    advisor.setTransactionAttributeSource(transactionAttributeSource());
    advisor.setAdvice(transactionInterceptor());
    if (this.enableTx != null) {
      advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
    }
    return advisor;
  }
 
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionAttributeSource transactionAttributeSource() {
    return new AnnotationTransactionAttributeSource();
  }
 
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionInterceptor transactionInterceptor() {
    TransactionInterceptor interceptor = new TransactionInterceptor();
    interceptor.setTransactionAttributeSource(transactionAttributeSource());
    if (this.txManager != null) {
      interceptor.setTransactionManager(this.txManager);
    }
    return interceptor;
  }
 
}

TransactionInterceptor類,事務(wù)調(diào)用:invokeWithinTransaction()方法為最終執(zhí)行的方法

@Override
  @Nullable
  public Object invoke(MethodInvocation invocation) throws Throwable {
    // Work out the target class: may be {@code null}.
    // The TransactionAttributeSource should be passed the target class
    // as well as the method, which may be from an interface.
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
 
    // Adapt to TransactionAspectSupport's invokeWithinTransaction...
    return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
  }

TransactionAspectSupport類的最終事務(wù)方法執(zhí)行:

@Nullable
  protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
      final InvocationCallback invocation) throws Throwable {
 
    // If the transaction attribute is null, the method is non-transactional.
    TransactionAttributeSource tas = getTransactionAttributeSource();
    final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
 
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      // Standard transaction demarcation with getTransaction and commit/rollback calls.
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
 
      Object retVal;
      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.proceedWithInvocation();
      }
      catch (Throwable ex) {
        // target invocation exception
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
      }
      finally {
        cleanupTransactionInfo(txInfo);
      }
      commitTransactionAfterReturning(txInfo);
      return retVal;
    }
 
    else {
      final ThrowableHolder throwableHolder = new ThrowableHolder();
 
      // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
      try {
        Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
          TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
          try {
            return invocation.proceedWithInvocation();
          }
          catch (Throwable ex) {
            if (txAttr.rollbackOn(ex)) {
              // A RuntimeException: will lead to a rollback.
              if (ex instanceof RuntimeException) {
                throw (RuntimeException) ex;
              }
              else {
                throw new ThrowableHolderException(ex);
              }
            }
            else {
              // A normal return value: will lead to a commit.
              throwableHolder.throwable = ex;
              return null;
            }
          }
          finally {
            cleanupTransactionInfo(txInfo);
          }
        });
 
        // Check result state: It might indicate a Throwable to rethrow.
        if (throwableHolder.throwable != null) {
          throw throwableHolder.throwable;
        }
        return result;
      }
      catch (ThrowableHolderException ex) {
        throw ex.getCause();
      }
      catch (TransactionSystemException ex2) {
        if (throwableHolder.throwable != null) {
          logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
          ex2.initApplicationException(throwableHolder.throwable);
        }
        throw ex2;
      }
      catch (Throwable ex2) {
        if (throwableHolder.throwable != null) {
          logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
        }
        throw ex2;
      }
    }
  }

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java自定義數(shù)組列表的實(shí)現(xiàn)操作

    Java自定義數(shù)組列表的實(shí)現(xiàn)操作

    這篇文章主要介紹了Java自定義數(shù)組列表的實(shí)現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Scala小程序詳解及實(shí)例代碼

    Scala小程序詳解及實(shí)例代碼

    這篇文章主要介紹了Scala 第一個Scala小程序詳解的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Springboot集成JUnit5優(yōu)雅進(jìn)行單元測試的示例

    Springboot集成JUnit5優(yōu)雅進(jìn)行單元測試的示例

    這篇文章主要介紹了Springboot集成JUnit5優(yōu)雅進(jìn)行單元測試的示例,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-10-10
  • Spring Boot整合swagger使用教程詳解

    Spring Boot整合swagger使用教程詳解

    這篇文章主要介紹了Spring Boot整合swagger使用教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Activiti流程引擎對象及配置原理解析

    Activiti流程引擎對象及配置原理解析

    這篇文章主要介紹了Activiti流程引擎對象及配置原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • java過濾html標(biāo)簽獲取純文本信息的實(shí)例

    java過濾html標(biāo)簽獲取純文本信息的實(shí)例

    今天小編就為大家分享一篇java過濾html標(biāo)簽獲取純文本信息的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • 詳解Spring簡單容器中的Bean基本加載過程

    詳解Spring簡單容器中的Bean基本加載過程

    本篇將對定義在 XMl 文件中的 bean,從靜態(tài)的的定義到變成可以使用的對象的過程,即 bean 的加載和獲取的過程進(jìn)行一個整體的了解
    2017-05-05
  • 使用eclipse導(dǎo)入javaWeb項(xiàng)目的圖文教程

    使用eclipse導(dǎo)入javaWeb項(xiàng)目的圖文教程

    這篇文章主要介紹了如何使用eclipse導(dǎo)入別人的javaWeb項(xiàng)目,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Java中的MapStruct的使用方法代碼實(shí)例

    Java中的MapStruct的使用方法代碼實(shí)例

    這篇文章主要介紹了Java中的MapStruct的使用方法代碼實(shí)例,mapstruct是一種實(shí)體類映射框架,能夠通過Java注解將一個實(shí)體類的屬性安全地賦值給另一個實(shí)體類,有了mapstruct,只需要定義一個映射器接口,聲明需要映射的方法,需要的朋友可以參考下
    2023-10-10
  • 教你用IDEA配置JUnit并進(jìn)行單元測試

    教你用IDEA配置JUnit并進(jìn)行單元測試

    今天教各位小伙伴怎么用IDEA配置JUnit并進(jìn)行單元測試,文中有非常詳細(xì)的圖文介紹及代碼示例,對正在學(xué)習(xí)IDEA的小伙伴有很好的幫助,需要的朋友可以參考下
    2021-05-05

最新評論

高雄县| 兴安县| 莎车县| 宕昌县| 赣榆县| 偃师市| 大安市| 石门县| 邓州市| 昌平区| 阿拉善盟| 安溪县| 江达县| 安泽县| 花莲市| 石棉县| 峨眉山市| 那坡县| 息烽县| 祁东县| 尚志市| 南开区| 南丰县| 仙游县| 万州区| 罗平县| 巴彦淖尔市| 晋宁县| 沙田区| 扶绥县| 玉屏| 乐至县| 宝应县| 武城县| 泗洪县| 东方市| 腾冲县| 定结县| 涞源县| 阿拉善左旗| 江津市|