Spring事务是基于AOP代理完成的,有了前面的AOP源码分析基础,Spring事务理解起来就比较简单了,我们先看一看Spring中的注解版事务配置例子:
Spring配置类:同开启AOP功能一样,事务功能也需要通过注解@EnableTransactionManagement进行开启,同时需要配置事务管理器,默认使用DataSourceTransationManager事务管理器。
@ComponentScan("ts")
@EnableTransactionManagement
@EnableAspectJAutoProxy
@Configurable
public class TsConfig {
// 配置数据源
@Bean
public DataSource dataSource()throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("w4467106");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setConnectionCustomizerClassName(YourConnectionCustomizer.class.getName());
return dataSource;
}
// 配置数据库操作辅助组件
@Bean
public JdbcTemplate jdbcTemplate()throws Exception{
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
// 配置事务管理器
@Bean
public PlatformTransactionManager transactionManager()throws Exception{
return new DataSourceTransactionManager(dataSource());
}
}
这里有一个坑在这说一下,当时按照网上配置完事务后发现发生异常后事务怎么也不回滚,Mysql引擎也是InnoDB最终发现是c3p0包中的ComboPooledDataSource数据源的原因,默认ComboPooledDataSource数据源在开启事务前不会关闭数据库连接的自动提交所以导致事务不会回滚,需要继承AbstractConnectionCustomizer类来将数据库连接自动提交关闭掉。
public class YourConnectionCustomizer extends AbstractConnectionCustomizer {
@Override
public void onCheckOut(Connection c, String parentDataSourceIdentityToken) throws Exception {
super.onCheckOut(c, parentDataSourceIdentityToken);
c.setAutoCommit(false);
}
}
言归正传,我们一起来探究Spri