Spring声明式事物原理分析

 基础准备 pom 

<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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.springannotation.test</groupId>
    <artifactId>NddSpring</artifactId>
    <version>1</version>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
            <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
        
                <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>
    </dependencies>

</project>

基础准备 配置 

package com.lkd.config;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.lkd.aop.LogAspects;
import com.lkd.aop.MathCalculator;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.lkd")
@EnableTransactionManagement
public class AopConfig {
	
	@Bean
	public MathCalculator calu() {
		return new MathCalculator();
	}
	
	@Bean
	public LogAspects aspects() {
		return new LogAspects();
	}
	@Bean
	public Object obj() {
		return new Object();
	}
	
	@Bean
	public DataSource student() throws Exception {
		ComboPooledDataSource  student  =new ComboPooledDataSource();
		student.setUser("root");
		student.setPassword("123456");
		//student.setDriverClass("com.mysql.jdbc.driver");
		student.setDriverClass("com.mysql.jdbc.Driver");
		student.setJdbcUrl("jdbc:mysql://localhost:3306/mytransction");
		return student;
	}
	@Bean
	public DataSource student2() throws Exception {
		ComboPooledDataSource  student  =new ComboPooledDataSource();
		student.setUser("root");
		student.setPassword("123456");
		//student.setDriverClass("com.mysql.jdbc.driver");
		student.setDriverClass("com.mysql.jdbc.Driver");
		student.setJdbcUrl("jdbc:mysql://localhost:3306/myt2");
		return student;
	}
	
	@Bean
	public JdbcTemplate jdbcTemplate1(DataSource student) {
		return new JdbcTemplate(student);
	}
	@Bean
	public JdbcTemplate jdbcTemplate2(DataSource student2) {
		return new JdbcTemplate(student2);
	}
	
	@Bean
	public MysqlDataSource student3() {
		MysqlDataSource student = new MysqlDataSource();
		student.setUser("root");
		student.setPassword("123456");
		//student.setDriverClass("com.mysql.jdbc.driver");
		student.setURL("jdbc:mysql://localhost:3306/myt2");
		return student;
		
	}
	@Bean
	public JdbcTemplate jdbcTemplate3(DataSource student3) {
		return new JdbcTemplate(student3);
	}
	
	@Bean
	public PlatformTransactionManager txmanager() throws Exception {
		return new DataSourceTransactionManager(student());
	}
}

  开始分析 

  @EnableTransactionManagement 开启声明式事务功能 

     为容器中导入TransactionManagementConfigurationSelector,它又会容器中导入 AutoProxyRegistrar(imp BeanDefinitionRegister)其作用为容器注入 InfrastructureAdvisorAutoProxyCreator 自动代理增强组件;利用后置处理器机制在对象创建以后

                                                                 包装对象返回一个代理对象;

                                         ProxyTransactionManagementConfiguration  给容器注入事物增强器 (解析注解) AnnotationTransactionAttributeSource;给容器中注入事物拦截器 TransactionInterceptor                                                                   ,保存了事物属性信息包括事务管理器

    a: 先获取事物属性TransactionAttribute,再获取PlatformTransactionManager平台事物管理器,未在Transctional注解中指定事物,则会在ioc容器中根据PlatFormTransctionManager类型的事物管理器对象

                                                                 

  

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

    /**
     * {@inheritDoc}
     * @return {@link ProxyTransactionManagementConfiguration} or
     * {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
     * {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
     */
    @Override
    protected String[] selectImports(AdviceMode adviceMode) {
        switch (adviceMode) {
            case PROXY:
                return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
            case ASPECTJ:
                return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
            default:
                return null;
        }
    }

 

 

 

  执行过程中出现异常

	protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
			throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				completeTransactionAfterThrowing(txInfo, ex);//出现异常进行回滚
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

  

    总结 : 事物实际上在spring维度是对AOP的应用,掌握了Aop原理,事物则会理解起来贼tm容易。如果AOP不清楚的可以看我Aop解析。

  https://www.cnblogs.com/leaveast/p/10829917.html

posted on 2019-05-10 17:50  闯入你笑颜  阅读(148)  评论(0编辑  收藏  举报

导航