美文网首页文字欲
Spring 声明式事务

Spring 声明式事务

作者: 架构师Javaspring | 来源:发表于2019-07-03 19:58 被阅读2次

    声明式事务:

    环境搭建:

    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

    * 最终会从容器中按照类型获取一个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">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.spring</groupId>

    <artifactId>spring-annotation</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <dependencies>

    <dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-context</artifactId>

    <version>5.1.5.RELEASE</version>

    </dependency>

    <dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-aspects</artifactId>

    <version>5.1.5.RELEASE</version>

    </dependency>

    <dependency>

    <groupId>junit</groupId>

    <artifactId>junit</artifactId>

    <version>4.10</version>

    <scope>test</scope>

    </dependency>

    <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->

    <dependency>

        <groupId>com.mchange</groupId>

        <artifactId>c3p0</artifactId>

        <version>0.9.5.2</version>

    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->

    <dependency>

        <groupId>mysql</groupId>

        <artifactId>mysql-connector-java</artifactId>

        <version>5.1.40</version>

    </dependency>

    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-jdbc</artifactId>

        <version>5.1.5.RELEASE</version>

    </dependency>

    </dependencies>

    </project>

    相关文章

      网友评论

        本文标题:Spring 声明式事务

        本文链接:https://www.haomeiwen.com/subject/hkxhhctx.html