1、事务保证数据一致性问题,只需要加上@Transactional 2、纯手写SpringAop环绕通知+手动事务就可以声明事务
@Repository
public class OrderDao {
@Autowired()
private JdbcTemplate jdbcTemplate;
public void addOrder() {
jdbcTemplate.update("insert into order_info values(null,'mayikt','zhangsan','1111')");
}
}
@Configuration
@ComponentScan("com.mayikt")
// @EnableTransactionManagement 实际上帮助我们开启了aop
@EnableTransactionManagement
public class MyConfig {
//注入到ioc容器中 beanid =dataSource class=DataSource类的完整路径地址
// 配置我们的数据源
@Bean
public DataSource dataSource() {
MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("root");
mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8");
mysqlDataSource.setDatabaseName("test");
return mysqlDataSource;
}
/**
* 注入JdbcTemplate
*/
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
// 多数据源如何实现
//@EnableTransactionManagement 开启事务注解
@Bean
public PlatformTransactionManager platformTransactionManager(){
return new DataSourceTransactionManager(dataSource());
}
}
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Transactional
public void addOrder() {
try {
orderDao.addOrder();
int i = 1 / 0; // 如果报错的情况下肯定是会插入到数据库中
} catch (Exception e) {
}
}
}
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!-- mysql 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
@EnableTransactionManagement//开启事务
@Import({TransactionManagementConfigurationSelector.class})
TransactionManagementConfigurationSelector的祖宗是ImportSelector
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {//向IOC容器中注入Bean对象
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, (Object)null);
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
将InfrastructureAdvisorAutoProxyCreator注入到IOC容器中:
下面回到
BeanId:transactionInterceptor;value为:TransactionInterceptor这个对象
打印所有注册的Bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory myConfig orderDao orderServiceImpl org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration org.springframework.transaction.config.internalTransactionAdvisor transactionAttributeSource transactionInterceptor【】【】【】【】这里 org.springframework.transaction.config.internalTransactionalEventListenerFactory dataSource jdbcTemplate platformTransactionManager org.springframework.aop.config.internalAutoProxyCreator【】【】【】【】这里
加上@EnableTransactionManagement这个注解将 :transactionInterceptor,和org.springframework.aop.config.internalAutoProxyCreator这两个类注入到IOC容器中
下面重点分析这两个类【transactionInterceptor】,【internalAutoProxyCreator】
我们一旦吧这个类:InfrastructureAdvisorAutoProxyCreator,Bean对象在初始化时,会判断是否需要创建代理类。
InfrastructureAdvisorAutoProxyCreator的祖宗就是AbstractAutoProxyCreator
@EnableTransactionManagement这个注解,实际帮我门开启了AOP
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
springaop在事务进行调用的时候会走transactionInterceptor进行拦截
执行目标方法,进入invoke()
1.@EnableTransactionManagement开启到我们的事务 2.@Import(TransactionManagementConfigurationSelector.class) 3. AdviceMode mode() default AdviceMode.PROXY;默认使用 PROXY选择器 4.return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; 5.AutoProxyRegistrar会将InfrastructureAdvisorAutoProxyCreator注册到IOC容器中; ##BeanId=internalAutoProxyCreator ##value=InfrastructureAdvisorAutoProxyCreator 6.ProxyTransactionManagementConfiguration将以下对象注入到IOC容器中: ##BeanId:transactionInterceptor ##value:TransactionInterceptor对象
重点分析:InfrastructureAdvisorAutoProxyCreator、tansactionInterceptor
InfrastructureAdvisorAutoProxyCreator祖宗就是我们的后置处理器 Bean对象在初始化之后都会判断是否需要创建代理类(根据是否有加上@Transactional) InfrastructureAdvisorAutoProxyCreator 祖宗就是AbstractAutoProxyCreator前置和后置处理