简介
啥事事物? ACID ,?这里不做解释,我们只分析spring是如何实现事物的,原理其实也是aop 思想,即执行目标方法,
- 方法异常,需要回滚吗?,通知方法进行回滚
- 方法正常,后置通知执行事物提交
示例
老规矩,没有代码,说不清楚问题。先看下边案例,执行user 插入需要进行事物,插入方法执行有误,就进行回滚(最经典的还是,转钱的示例,大家懂得)
环境搭建
- 1、导入相关依赖
数据源、数据库驱动、Spring-jdbc模块 - 2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
- 3、给方法上标注 @Transactional 表示当前方法是一个事务方法;
- 4、 @EnableTransactionManagement 开启基于注解的事务管理功能;
@EnableXXX - 5、配置事务管理器来控制事务;
@Bean
public PlatformTransactionManager transactionManager()
目标方法类
dao层
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void insert() {
String sql = "INSERT INTO `user`(password,ages) VALUES(?,?)";
String password = UUID.randomUUID().toString().substring(0, 5);
jdbcTemplate.update(sql, password, 19);
}
}
service层
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Transactional
public void insertUser(){
userDao.insert();
//otherDao.other();xxx
System.out.println("插入完成...");
//int i = 10/0;
}
}
配置类
@EnableTransactionManagement
@ComponentScan("com.uu.anhusky.tx")
@Configuration
public class TxConfig {
// 数据源
@Bean
public DataSource dataSource() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("root123");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
//
@Bean
public JdbcTemplate jdbcTemplate() throws Exception{
//Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
// 注册事务管理器在容器中
@Bean
public PlatformTransactionManager transactionManager() throws Exception{
return new DataSourceTransactionManager(dataSource());
}
}
测试类
public class IOCTest_Tx {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(TxConfig.class);
UserService userService = applicationContext.getBean(UserService.class);
userService.insertUser();
applicationContext.close();
}
}
原理分析?
1 )、@EnableTransactionManagement
利用TransactionManagementConfigurationSelector给容器中会导入组件 导入两个组件: - AutoProxyRegister - ProxyTransactionManagementConfiguration
2 )、 AutoProxyRegister 做了神马?
给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件; InfrastructureAdvisorAutoProxyCreator:? 利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;
3 )、 ProxyTransactionManagementConfiguration 做了神马?
给容器中注册事物增强器: 1 ) 事物增强器要用事物注解的信息,AnnotationTransactionAttributeSource解析事务注解 2 )事物拦截器: TransactionInterceptor;保存了事务属性信息,事务管理器; 它是一个MethodInterceptor: 在目标方法执行的时候; 执行拦截器链: 事物拦截器: 1)、先获取事物相关的属性 2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionManager,最终会从容器中按照类型获取一个PlatformTransactionManager 3) 、执行目标烦那个发 如果异常,获取到事物管理器,利用事物管理回滚操作; 如果正常,利用事物管理器,提交事物
事物拦截器执行方法片段截图如下: