Spring注解驱动开发之声明式事务

Updated on with 0 views and 0 comments

简单使用

1.导入相关依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>

2.配置数据源、JdbcTemplate(Spring提供的简化数据库操作工具)

@Bean
    public DataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser("root");
        dataSource.setPassword("458974tl");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true");
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate() throws PropertyVetoException {
        //Spring对@ Configuration类会特殊处理,给容器中加组件的方法,多次调用都只是从容器中找组件
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }

3.给方法标志上@Transactional标注当前方法是一个事务方法

@Transactional
    public void insert() {
        String sql = "insert into user(name,age,sex) value(?,?,?)";
        UUID.randomUUID().toString().substring(0,5);
        jdbcTemplate.update(sql,"wu",18,1);
    }

4.开启基于注解的事务管理功能

@EnableTransactionManagement
public class TxConfig {
}

5.配置事务管理器来控制事务

//注册事务管理器在容器中
    @Bean
    public PlatformTransactionManager transactionManager() throws PropertyVetoException {
        return new DataSourceTransactionManager(dataSource());
    }

原理

1.@EnableTransactionManagement
利用TransactionManagementConfigurationSelector给容器中导入组件,导入两个组件:AutoProxyRegistrar、ProxyTransactionManagementConfiguration

(1)AutoProxyRegistrar:给容器中注册一个InfrastructureAdvisorAutoProxyCreator组件、AnnotationAwareAspectJAutoProxyCreator组件

InfrastructureAdvisorAutoProxyCreator:利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用

(2)ProxyTransactionManagementConfiguration

  • 给容器中注册事务增强器:事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
  • 事务拦截器:TransactionInterceptor,保存了事务属性信息,事务管理器,他是一个MethodInterceptor,在目标方法执行的时候,执行拦截器链
    • 先获取事务相关属性
    • 再获取PlatformTransactionManager,如果事先没有执行任何ransactionManager,最终会从容器中按照一定类型获取一个
    • 执行目标方法,如果异常,获取到事务管理器,利用它进行回滚操作,如果正常,利用事务管理器提交事务