天天看點

Spring Transaction@EnableTransactionManagementAutoProxyRegistrarProxyTransactionManagementConfiguration事務隔離級别事務傳播行為

Spring Transaction

  • @EnableTransactionManagement
  • AutoProxyRegistrar
  • ProxyTransactionManagementConfiguration
    • 給容器中注冊事務增強器transactionAdvisor
    • 事務攔截器transactionInterceptor
  • 事務隔離級别
  • 事務傳播行為

@EnableTransactionManagement

利用TransactionManagementConfigurationSelector給容器中會導入元件

  • AutoProxyRegistrar
  • ProxyTransactionManagementConfiguration
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;
	}
}
           

AutoProxyRegistrar

  • 給容器中注冊一個 InfrastructureAdvisorAutoProxyCreator 元件;
  • 利用後置處理器機制在對象建立以後,包裝對象,傳回一個代理對象(增強器),代理對象執行方法利用攔截器鍊進行調用;

ProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration是個@Configuration

給容器中注冊事務增強器transactionAdvisor

  • 事務增強器要用事務注解的資訊,AnnotationTransactionAttributeSource解析事務注解

事務攔截器transactionInterceptor

  • TransactionInterceptor: 儲存了事務屬性資訊,事務管理器;
  • TransactionInterceptor是一個 MethodInterceptor;

    在目标方法執行的時候,執行攔截器鍊;

    隻有事務攔截器:

  1. 先擷取事務相關的屬性
  2. 再擷取PlatformTransactionManager,如果事先沒有添加指定任何transactionmanger

    最終會從容器中按照類型擷取一個PlatformTransactionManager;

  3. 執行目标方法

    如果異常,擷取到事務管理器,利用事務管理復原操作;

    如果正常,利用事務管理器,送出事務

事務隔離級别

@Transactional(isolation = Isolation.READ_UNCOMMITTED) 讀取未送出資料(會出現髒讀, 不可重複讀),基本不使用

@Transactional(isolation = Isolation.READ_COMMITTED)(SQLSERVER預設) 讀取已送出資料(會出現不可重複讀和幻讀)

@Transactional(isolation = Isolation.REPEATABLE_READ) 可重複讀(會出現幻讀)

@Transactional(isolation = Isolation.SERIALIZABLE) 串行化

事務傳播行為

@Transactional(propagation=Propagation.REQUIRED) 如果有事務, 那麼加入事務, 沒有的話建立一個(預設情況)

@Transactional(propagation=Propagation.NOT_SUPPORTED) 容器不為這個方法開啟事務

@Transactional(propagation=Propagation.REQUIRES_NEW) 不管是否存在事務,都建立一個新的事務,原來的挂起,新的執行完畢,繼續執行老的事務

@Transactional(propagation=Propagation.MANDATORY) 必須在一個已有的事務中執行,否則抛出異常

@Transactional(propagation=Propagation.NEVER) 必須在一個沒有的事務中執行,否則抛出異常(與Propagation.MANDATORY相反)

@Transactional(propagation=Propagation.SUPPORTS) 如果其他bean調用這個方法,在其他bean中聲明事務,那就用事務。如果其他bean沒有聲明事務,那就不用事務