zoukankan      html  css  js  c++  java
  • Spring注解驱动开发之声明式事务

      前言:现今SpringBoot、SpringCloud技术非常火热,作为Spring之上的框架,他们大量使用到了Spring的一些底层注解、原理,比如@Conditional、@Import、@EnableXXX等。如果掌握这些底层原理、注解,那么我们对这些高层框架就能做到高度定制,使用的游刃有余

      本章内容:Spring声明式事务的使用与源码分析

    一、环境搭建

      1、导入相关依赖
        数据源、数据库驱动、Spring-jdbc模块
      2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
      3、给方法上标注 @Transactional 表示当前方法是一个事务方法;
      4、 @EnableTransactionManagement 开启基于注解的事务管理功能;
        @EnableXXX与开启AOP功能类似
      5、配置事务管理器来控制事务;
      @Bean
      public PlatformTransactionManager transactionManager()

    测试:

    @EnableTransactionManagement
    @ComponentScan("com.atguigu.tx")
    @Configuration
    public class TxConfig {
        
        //数据源
        @Bean
        public DataSource dataSource() throws Exception{
            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;
        }
        
        //
        @Bean
        public JdbcTemplate jdbcTemplate() throws Exception{
            //Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
            return jdbcTemplate;
        }
        
        //注册事务管理器在容器中
        @Bean
        public PlatformTransactionManager transactionManager() throws Exception{
            return new DataSourceTransactionManager(dataSource());
        }
        
    }

    @Repository
    public class UserDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
        public void insert(){
            String sql = "INSERT INTO `tbl_user`(username,age) VALUES(?,?)";
            String username = UUID.randomUUID().toString().substring(0, 5);
            jdbcTemplate.update(sql, username,19);
            
        }
    }
    
    @Service
    public class UserService {
        
        @Autowired
        private UserDao userDao;
        
        @Transactional
        public void insertUser(){
            userDao.insert();
            //otherDao.other();xxx
            System.out.println("插入完成...");
            int i = 10/0;
        }
    
    public class IOCTest_Tx {  
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = 
                    new AnnotationConfigApplicationContext(TxConfig.class);
        
            UserService userService = applicationContext.getBean(UserService.class);
            
            userService.insertUser();
            applicationContext.close();
        }
    }
    

    二、源码分析

    原理:
      1)、@EnableTransactionManagement
      利用TransactionManagementConfigurationSelector给容器中会导入两个组件:
        AutoProxyRegistrar
        ProxyTransactionManagementConfiguration
      2)、AutoProxyRegistrar:
      给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件;
      InfrastructureAdvisorAutoProxyCreator:利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;

      3)、ProxyTransactionManagementConfiguration 作用:
      1、给容器中注册事务增强器:
        1)、事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
        2)、事务拦截器:
          TransactionInterceptor:保存了事务属性信息,事务管理器,他是一个 MethodInterceptor,在目标方法执行的时候,执行拦截器链
            事务拦截器执行:
              1)、先获取事务相关的属性
              2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger
              最终会从容器中按照类型获取一个PlatformTransactionManager;
              3)、执行目标方法
                如果异常,获取到事务管理器,利用事务管理回滚操作;
                如果正常,利用事务管理器,提交事务


    相关源码:

      

      

      

  • 相关阅读:
    ios 手势加变形
    ios 懒加载
    [leetCode]1111. 有效括号的嵌套深度
    [leetCode]面试题 08.07. 无重复字符串的排列组合
    [leetCode]46. 全排列
    [leetCode]37. 解数独
    [leetCode]面试题 08.09. 括号
    torch.Tensor 与 numpy.ndarray的相互转化
    [leetCode]93. 复原IP地址
    [leetCode]15. 三数之和
  • 原文地址:https://www.cnblogs.com/qzlcl/p/10982081.html
Copyright © 2011-2022 走看看