天天看点

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没有声明事务,那就不用事务