天天看點

spring 事務淺析

文章目錄

    • 1 DataSourceTransactionManagerAutoConfiguration:事務自動配置類
    • 2 TransactionAutoConfiguration:事務自動配置類
    • 3 @EnableTransactionManagement
      • ProxyTransactionManagementConfiguration
      • AutoProxyRegistrar
    • 4 BeanFactoryTransactionAttributeSourceAdvisor:事務功能核心類
    • 5 TransactionInterceptor:代理增強類
    • 6 getTransaction:事務資訊生産方法
    • 7 業務 mapper 流程
    • shardingjdbc 相關

1 DataSourceTransactionManagerAutoConfiguration:事務自動配置類

執行個體化 DataSourceTransactionManager 并調用 transactionManagerCustomizers

2 TransactionAutoConfiguration:事務自動配置類

  • 執行個體化 TransactionManagerCustomizers
  • 執行個體化 TransactionTemplate
  • 調用 @EnableTransactionManagement

3 @EnableTransactionManagement

注入 AutoProxyRegistrar、ProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration

注入:BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource、TransactionInterceptor,核心是 advisor,做 事務切面用

AutoProxyRegistrar

用于注冊 Aop beanPostProcessor 的 beanDefinition。和 AopAutoConfiguration 注冊的是同一個邏輯,僅僅是 class 不一樣,但是最終取的是優先級最高的 AnnotationAwareAspectJAutoProxyCreator 類作為最終的 beanPostProcessor 執行個體

4 BeanFactoryTransactionAttributeSourceAdvisor:事務功能核心類

BeanFactoryTransactionAttributeSourceAdvisor 内置了 TransactionAttributeSourcePointcut,

并在步驟 3 中設定了 TransactionInterceptor 和 AnnotationTransactionAttributeSource

  • TransactionInterceptor:走切面流程的
  • AnnotationTransactionAttributeSource:内部使用 TransactionAnnotationParser 來解析 方法上或方法對應的類上有沒有 @Transactional 注解
  • TransactionAttributeSourcePointcut:切點類,内部使用 AnnotationTransactionAttributeSource 來判斷方法是否需要被增強

5 TransactionInterceptor:代理增強類

  1. 進入切面後 調用 invokeWithinTransaction() 方法
  2. 擷取 AnnotationTransactionAttributeSource 執行個體,調用其 getTransactionAttribute() 方法擷取 TransactionAttribute
  3. 調用 createTransactionIfNecessary() 方法
    1. 調用 AbstractPlatformTransactionManager#getTransaction 方法,擷取事務資訊,并放入 threadLocal(使得同一個事務内的其它資料庫操作拿到同一事務資訊)
    2. 調用原生方法

6 getTransaction:事務資訊生産方法

核心是 doBegin 方法

  1. 從 datasource 中**擷取 connection ** (1)
  2. set auto commit 為 false
  3. 如果 read only,則設定 SET TRANSACTION READ ONLY
  4. 将 datasource 和 connectionHolder 綁定到 threadLocal,以便下次直接擷取

7 業務 mapper 流程

SqlSessionInterceptor#invoke 方法

  1. 擷取 session (2),并且如果有事務,則放入 threadLocal 中。key:sessionFactory

在 SimpleExecutor#prepareStatement 的時候,會擷取 connection,這時候如果有事務的話,會先從 threadLocal 中擷取(一般是有的了,在 getTransaction 4 階段設定了),如果沒有則建立,并加入到 threadLocal 中!!

shardingjdbc 相關

org.apache.shardingsphere.shardingjdbc.jdbc.adapter.WrapperAdapter#recordMethodInvocation

這個方法,緩存要操作的動作!!!因為當時 connection 還是 shardingconnection

org.apache.shardingsphere.shardingjdbc.jdbc.adapter.WrapperAdapter#replayMethodsInvocation。之後在調用這個來執行

org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement#prepare 擷取 sql 相關資訊,路由等

org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement#initPreparedStatementExecutor 擷取真正的 connection 和 statement 資訊,分組,供最終執行

org.apache.shardingsphere.shardingjdbc.jdbc.adapter.AbstractConnectionAdapter#rollback

shardingjdbc 事務的核心:

AbstractConnectionAdapter、cachedConnections

最終 commit 和 rollback 都會周遊 cachedConnections 去做操作

繼續閱讀