Spring注解(事务)
spring操作数据库 jdbc
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
这个简化数据库操作 及其事务控制
maven依赖就导入了 jdbc 和 tx
如果用mybatis,则还需要导入orm模块,做事务控制时候,orm模块支持各种版本的mybatis
配置数据源和jdbcTemplate(Spring 提供简化数据库操作的工具)
xml中:
<tx: annnotation-driven/>
config:
@EnableTransactionManagement
@ComponentScan(value="com.toov5")
@Configuration
public class TxConfig {
@Bean
public ComboPooledDataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("12345");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate() throws PropertyVetoException {
// Spring 对 @Configuration列特殊处理; 给容器加组件方法,多次调用都是从容器中找组件
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); //调用 dataSource() 方法
return jdbcTemplate;
}
//事务管理器 管理数据源 事务开始 回滚之类的都是有事务管理器来做
@Bean //注册事务管理器在容器中
public PlatformTransactionManager transactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(dataSource());
}
}
(套路都是 @EnableXXX)
service:
@Service
public class BookService {
@Autowired
private BookDao bookDao;
@Transactional
public void insertUser() {
bookDao.insertUser();
}
}
步骤:
1、开启事务管理功能
2、@Transactional 标注到方法
3、配置事务管理器到容器
看下源码:
大家可以按照这个思路点击或者debug调试查看:
1 @EnableTransactionManagement
利用 TransactionManagementConfigurationSelector 给容器中导入两个组件:
AutoProxyRegisrar
ProxyTransactionManagementConfiguration
2 AutoProxyRegistrar
给容器注册一个 InfrastructureAdvisorAutoProxyCreator组件
InfrastructureAdvisorAutoProxyCreator 利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器) 代理对象执行方法利用拦截器链进行调用
3 ProxyTransactionManagementConfiguration 给容器注册事务增强器
1 给容器中注册事务增强器
事务增强器要用事务注解的信息 AnnotationTransactionAttributeSource 解析事务注解
事务拦截器 TransactionInterceptor 保存了事务属性信息 、事务管理器
是个MethodInterceptor 方法拦截器
在目标方法执行的时候 执行拦截器链 : 先获取事务相关的属性 再获取PlantformTransactionManager 平台的事务管理器。如果没有实现添加任何TransactionManager, 则最终会从容器中按照类型
获取一个PlantformTransactionManager
执行目标方法,如果异常,获取事务管理器,利用事务管理器 回滚操作。 如果正常利用事务管理器提交事务。