声明式事务:
环境搭建:
1、导入相关依赖
数据源、数据库驱动、Spring-jdbc模块
2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
3、给方法上标注@Transactional标识当前方法是一个事务方法;
4、@EnableTransactionManagement 开启基于注解的事务管理功能;
5、配置事务管理器来控制事务;
@Bean
public PlatformTransactionManager platformTransactionManager()
原理:
1、@EnableTransactionManagement
利用TransactionManagementConfigurationSelector给容器中导入组件
导入两个组件
AutoProxyRegistrar
ProxyTransactionManagementConfiguration
2、AutoProxyRegistrar:
给容器中注册一个InfrastructureAdvisorAutoProxyCreator 组件;
InfrastructureAdvisorAutoProxyCreator:?
利用后置处理器记住在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;
3、ProxyTransactionManagementConfiguration 做了什么?
3.1 给容器中注册事务增强器
3.1.1 事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事物
3.1.2 事务拦截器:
TransactionInterceptor:保存了事务属性信息,事务管理器;
它是一个MethodInterceptor;
在目标方法执行的时候;
执行拦截器链;
事务拦截器:
a) 先获取事务相关的属性
b) 再获取PlatformTransactionManager,如果实现没有添加指定任何TransactionManager
最终会从容器中按照类型获取一个PlatformTransactionManager
c) 执行目标方法
如果异常,获取到事务管理器,利用事务管理器回滚操作;
如果正常,利用事务管理器,提交事务
package com.spring.tx;
import java.beans.PropertyVetoException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringValueResolver;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
-
声明式事务:
-
环境搭建:
-
1、导入相关依赖
-
数据源、数据库驱动、Spring-jdbc模块
-
2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
-
3、给方法上标注@Transactional标识当前方法是一个事务方法;
-
4、@EnableTransactionManagement 开启基于注解的事务管理功能;
-
5、配置事务管理器来控制事务;
-
@Bean
-
public PlatformTransactionManager platformTransactionManager()
-
原理:
-
1、@EnableTransactionManagement
-
利用TransactionManagementConfigurationSelector给容器中导入组件
-
导入两个组件
-
AutoProxyRegistrar
-
ProxyTransactionManagementConfiguration
-
2、AutoProxyRegistrar:
-
给容器中注册一个InfrastructureAdvisorAutoProxyCreator 组件;
-
InfrastructureAdvisorAutoProxyCreator:?
-
利用后置处理器记住在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;
-
3、ProxyTransactionManagementConfiguration 做了什么?
-
3.1 给容器中注册事务增强器
-
3.1.1 事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事物
-
3.1.2 事务拦截器:
-
TransactionInterceptor:保存了事务属性信息,事务管理器;
-
它是一个MethodInterceptor;
-
在目标方法执行的时候;
-
执行拦截器链;
-
事务拦截器:
-
a) 先获取事务相关的属性
-
b) 再获取PlatformTransactionManager,如果实现没有添加指定任何TransactionManager.在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
-
最终会从容器中按照类型获取一个PlatformTransactionManager
-
c) 执行目标方法
-
如果异常,获取到事务管理器,利用事务管理器回滚操作;
-
如果正常,利用事务管理器,提交事务
*/
@EnableTransactionManagement
@ComponentScan(“com.spring.tx”)
@PropertySource(“classpath:/dbconfig.properties”)
@Configuration
public class TxConfig implements EmbeddedValueResolverAware{
@Value(“${db.user}”)
private String user;
@Value(“${db.password}”)
private String password;
private String driverClass;
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
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 platformTransactionManager() throws Exception {
PlatformTransactionManager manager = new DataSourceTransactionManager(dataSource());
return manager;
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
String driverClass = resolver.resolveStringValue(“${db.driverClass}”);
this.driverClass = driverClass;
}
}
package com.spring.tx;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void insert() {
String sql = “insert into user(name,age) values(?,?)”;
String username = UUID.randomUUID().toString().substring(0, 5);
jdbcTemplate.update(sql,username,20);
}
}
package com.spring.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserDao dao ;
@Transactional
public void insert() {
dao.insert();
System.out.println(“>>>>>>>>>>>插入完成<<<<<<<<<<<”);
System.out.println(10/0);
}
}
package com.spring.test;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.spring.tx.TxConfig;
import com.spring.tx.UserService;
public class IOCTestOfTx {
@Test
public void test() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TxConfig.class);
UserService userService = applicationContext.getBean(UserService.class);
userService.insert();
applicationContext.close();
}
}
<project xmlns=“http://maven.apache.org/POM/4.0.0”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
4.0.0
com.spring
spring-annotation
0.0.1-SNAPSHOT
org.springframework
spring-context
5.1.5.RELEASE
org.springframework
spring-aspects
5.1.5.RELEASE
junit
junit
4.10
test
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>