1、定义
以方法为单位,进行事务控制;抛出异常,事务回滚。最小的执行单位为方法。决定执行成败是通过是否抛出异常来判断的,抛出异常即执行失败。
2、代码
(1) mysql建表语句
CREATE TABLE `t_student` (
`c_id` int(11) NOT NULL AUTO_INCREMENT,
`c_name` varchar(255) DEFAULT NULL,
`c_age` int(12) DEFAULT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
(2) pom
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
</dependencies>
(3) 配置文件
/**
* @Description:
* @Auther: zhurongsheng
* @Date: 2020/3/1 00:15
*/
@ComponentScan("com.spring")
@Configuration
@EnableTransactionManagement
public class SpringConfig {
//创建数据源
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
//jdbcTemplate能简化增删改查的操作
@Bean
public JdbcTemplate jdbcTemplate() throws PropertyVetoException{
return new JdbcTemplate(dataSource());
}
@Bean
public PlatformTransactionManager platformTransactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(dataSource());
}
}
(4) dao
/**
* @Description:
* @Auther: zhurongsheng
* @Date: 2020/3/1 00:14
*/
@Repository
public class StudentDao {
@Autowired
private JdbcTemplate jdbcTemplate;
//操作数据的方法
public void insert() {
String sql = "insert into `t_student` (c_name, c_age) values(?,?)";
jdbcTemplate.update(sql, "张三", 18);
throw new RuntimeException("IOC 测试");
}
}
(5) service
@Service
public class StudentService {
@Autowired
private StudentDao studentDao;
@Transactional
public void addStudent(){
studentDao.insert();
System.out.println("student insert success");
}
}
(6) 应用程序
public class SpringApplicationContext {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(SpringConfig.class);
StudentService studentService = applicationContext.getBean(StudentService.class);
studentService.addStudent();
}
}
3、@EnableTransactionManagement
(1) 作用:开启事务
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
/**
* 引入TransactionManagementConfigurationSelector.class
*/
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
/**
* 默认模式
*/
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
(2`) TransactionManagementConfigurationSelector
4、 AutoProxyRegistrar类作用
(1)引入InfrastructureAdvisorAutoProxyCreator类
(2) InfrastructureAdvisorAutoProxyCreator分析
看类图得到,跟切面AnnotationAwareAspectJAutoProxyCreator类图很很像:
InstantiationAwareBeanPostProcessor:bean创建的后置加强
Ordered:IOC初始化时,具有高优先级。
5、ProxyTransactionManagementConfiguration类作用
(1) 源码
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
//事务属性工厂
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
//设置事务本身属性
advisor.setTransactionAttributeSource(transactionAttributeSource());
//设置拦截方法
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
/**
* transactionAttributeSource bean:事务增强器需要用事务注解信息,使用这个类解析事务注解
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
//获取事务所有注解
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
//声明方法拦截
TransactionInterceptor interceptor = new TransactionInterceptor();
//设置事务属性
interceptor.setTransactionAttributeSource(transactionAttributeSource());
//如果事务管理器不为NULL,设置事务管理器
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
(2) 核心bean
(3) 调用方法
(4) TransactionAspectSupport invokeWithinTransaction方法
6 Debug
(1) CglibAopProxy intercept(跟AOP 一样 获取方法链…process)
(2) ReflectiveMethodInvocation proceed()
(3) TransactionAspectSupport invokeWithinTransaction