1. 搭建环境
①数据源 c3p0; ②数据库驱动 jdbc-connector-java;③spring-jdbc
配置数据源,配置事务管理器
@EnableTransactionManagement
@Configuration
@ComponentScan("com.cn.zj")
public class TxConfig {
@Bean
public DataSource dataSource() throws PropertyVetoException {ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 设置属性
dataSource.setUser("xxx");
dataSource.setPassword("xxx");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://139.9.95.160:3306/test");
return dataSource;
}
// 为了操作数据库方便,我们给数据容器中添加一个 JdbcTemplate
@Bean
public JdbcTemplate jdbcTemplate() throws PropertyVetoException {JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
@Bean
public PlatformTransactionManager platformTransactionManager() throws PropertyVetoException {return new DataSourceTransactionManager(dataSource());
}
}
2. 原理讲述
- 1. 利用 @EnableTransactionManagement 给容器中添加 TransactionManagementConfigurationSelector;这个选择器默认会给容器添加两个组件
- 2.AutoProxyRegistrar ==> 注册 InfrastructureAdvisorAutoProxyCreator;InfrastructureAdvisorAutoProxyCreator 等同于 aop 中的 AnnotaitonAwareAspectJAutoProxyCreator,利用后置处理器的机制,在对象创建后包装对象,返回代理对象(增强器);代理对象执行拦截器链
- 3.ProxyTransactionManagementConfiguration;①给容器中注册事务增强器;事务增强器要用事务的注解信息 AnnotationTransactionAttributeSource 解析事务②事务拦截器 TransactionInterceptor(他是一个方法拦截器 MethodInterceptor)在目标方法执行的时候执行拦截器链:1. 先获取事务相关的属性;2 获取 PlatformTransactionManager 如果没有,我们会创建一个 PlatformTransactionManager;3. 执行目标方法,如果事务异常就利用事务管理器回滚目标方法。没有异常也通过事务管理器进行提交;