13

2024-04-18 1527阅读

文章目录

  • Spring事务
    • 使用Spring框架对Mybatis整合
    • 事务的核心接口
      • PlatformTransactionManager平台事务管理器
      • TransactionStatus事务状态
      • TransactionDefinition事务定义
      • 事务的传播行为
      • TransactionTemplate
      • Transactional注解

        Spring事务

        使用Spring框架对Mybatis整合

        13

        上图中:绿色是手动注册的组件,黄色的是MapperScannerConfigure注册的组件

        1. 引入依赖
         
         
             org.mybatis
             mybatis-spring
             2.0.7
         
         
             org.springframework
             spring-jdbc
             5.2.15.RELEASE
         
        
        
        
            com.alibaba
            druid
            1.2.11
        
        
        1. 组件注册
        @Configuration
        @ComponentScan("com.coo1heisenberg.demo2")
        public class AppConfiguration {
        //    @Bean
        //    public SqlSessionFactory sqlSessionFactory() {
        //
        //        try {
        //            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
        //                    .build(Resources.getResourceAsStream("mybatis.xml"));
        //            return sqlSessionFactory;
        //        } catch (IOException e) {
        //            e.printStackTrace();
        //        }
        //        return null;
        //    }
            /**
             * mybatis-spring这个依赖提供了一个类,能够注册sqlSessionFactory组件
             *
             * sqlSessionFactoryBean implements FactoryBean
             */
            @Bean
            public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
                SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
                sqlSessionFactoryBean.setDataSource(dataSource);
                return sqlSessionFactoryBean;
            }
            @Bean
            public DataSource dataSource() {
                DruidDataSource dataSource = new DruidDataSource();
                dataSource.setDriverClassName("com.mysql.jdbc.Driver");
                dataSource.setUrl("jdbc:mysql://localhost:3306/coo1heisenberg?useSSL=false&characterEncoding=utf8");
                dataSource.setUsername("root");
                dataSource.setPassword("123456");
                return dataSource;
            }
            @Bean
            public MapperScannerConfigurer mapperScannerConfigurer() {
                MapperScannerConfigurer configurer = new MapperScannerConfigurer();
                // 使用set方法提供一些信息
                // 就会根据这些信息向mapper中注册组件
                configurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
                // sqlSessionFactory = applicationContext.getBean(beanName);
                configurer.setBasePackage("com.coo1heisenberg.demo2.mapper");
                return configurer;
            }
        }
        
        1. 在Service中可以直接注册Mapper
        @Service
        public class AccountServiceImpl implements AccountService {
        //    @Autowired
        //    SqlSessionFactory sqlSessionFactory;
            @Autowired
            AccountMapper accountMapper;
            @Override
            public int transfer(Integer fromId, Integer destId, Double money) {
        //        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //        AccountMapper mapper = sqlSession.getMapper(AccountMapper.class);
                Double fromMoney = accountMapper.selectByPrimaryKey(fromId) - money;
                Double destMoney = accountMapper.selectByPrimaryKey(destId) + money;
                accountMapper.upDate(fromId, fromMoney);
                int i = 1
                accountMapper.upDate(destId, destMoney);
                return 0;
            }
        }
        
        1. 测试文件
        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration(classes = AppConfiguration.class)
        public class MybatisSpringTest {
            @Autowired
            AccountService accountService;
            @Test
            public void test() {
                accountService.transfer(1, 2, 100.0);
            }
        }
        

        总结:Spring在Mybatis执行mapper的方法之后会立刻提交事务,而有时需要将多个方法放到一个事务里。


        事务的核心接口

        • PlatformTransactionManager 平台事务管理器
        • TransactionStatus 事务状态
        • TransactionDefinition 事务定义

          PlatformTransactionManager平台事务管理器

          • 平台事务管理器,Spring要管理事务,必须使用事务管理器
          • 有多种实现,通过实现此接口,Spring可以管理任何实现了这些接口的事务
          • 常见的事务管理器的实现:
            • DataSourceTransactionManager,jdbc开发时事务管理器,使用JdbcTemplate、MyBatis(SSM)
            • HibernateTransactionManager,Hibernate开发时事务管理器,整合Hibernate(SSH)
              public interface PlatformTransactionManager extends TransactionManager {
                // 开启事务
                  TransactionStatus getTransaction(@Nullable TransactionDefinition var1) 
                  throws TransactionException;
                
                // 提交事务
                  void commit(TransactionStatus var1) throws TransactionException;
                
                // 回滚事务
                  void rollback(TransactionStatus var1) throws TransactionException;
              }
              

              TransactionStatus事务状态

              • 获取事务的状态(回滚点、是否完成、是否新事务、是否回滚)属性,是一个过程值
              • 这个一般不需要关注
                public interface TransactionStatus extends TransactionExecution
                    , SavepointManager, Flushable {
                    // 是否有保存点
                  boolean hasSavepoint();
                    // 
                  void flush();
                }
                

                TransactionDefinition事务定义

                • 定义事务的名称、隔离级别、传播行为、超时时间长短、只读属性等
                  public interface TransactionDefinition {
                  // 定义了一些成员变量
                    int PROPAGATION_REQUIRED = 0;
                    int PROPAGATION_SUPPORTS = 1;
                    int PROPAGATION_MANDATORY = 2;
                    int PROPAGATION_REQUIRES_NEW = 3;
                    int PROPAGATION_NOT_SUPPORTED = 4;
                    int PROPAGATION_NEVER = 5;
                    int PROPAGATION_NESTED = 6;
                    int ISOLATION_DEFAULT = -1;
                    int ISOLATION_READ_UNCOMMITTED = 1;
                    int ISOLATION_READ_COMMITTED = 2;
                    int ISOLATION_REPEATABLE_READ = 4;
                    int ISOLATION_SERIALIZABLE = 8;
                    int TIMEOUT_DEFAULT = -1;
                  // 下面是提供默认值和对应的方法
                  // jdk1.8之后才提供的default
                    default int getPropagationBehavior() {
                      return 0;
                    }
                    default int getIsolationLevel() {
                      return -1;
                    }
                    default int getTimeout() {
                      return -1;
                    }
                    default boolean isReadOnly() {
                      return false;
                    }
                    @Nullable
                    default String getName() {
                      return null;
                    }
                    static TransactionDefinition withDefaults() {
                      return StaticTransactionDefinition.INSTANCE;
                    }
                  }
                  

                  事务的传播行为

                  • 指多个方法之间如何来共享事务:发生异常的情况,谁提交谁回滚
                  • REQUIRED (默认的事务传播行为)
                    • 一荣俱荣,同生共死
                      • 要么一起提交,要么一起回滚
                      • REQUIRES_NEW
                        • 自私型
                          • 部不会影响内部,内部会影响外围
                          • 内部的方法更重要
                          • NESTED
                            • 无私型
                              • 外围会影响内部,内部不会影响外围
                              • 外部的方法更重要
                              • 其他传播行为
                                传播行为描述
                                PROPAGATION_SUPPORTS支持当前事务,假设当前没有事务,就以非事务方式运行
                                PROPAGATION_MANDATORY支持当前事务,假设当前没有事务,就抛出异常
                                PROPAGATION_NOT_SUPPORTED以非事务方式运行操作。假设当前存在事务,就把当前事务挂起
                                PROPAGATION_NEVER以非事务方式运行,假设当前存在事务,则抛出异常

                                eg:

                                13

                                • config目录下的AppConfiguration注册组件
                                  @Bean
                                  public PlatformTransactionManager transactionManager(DataSource dataSource) {
                                      DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
                                      transactionManager.setDataSource(dataSource);
                                      return transactionManager;
                                  }
                                  
                                  • service目录下
                                        @Autowired
                                        PlatformTransactionManager platformTransactionManager;
                                        @Override
                                        public int transfer(Integer fromId, Integer destId, Double money) {
                                            Double fromMoney = accountMapper.selectByPrimaryKey(fromId) - money;
                                            Double destMoney = accountMapper.selectByPrimaryKey(destId) + money;
                                            // 开启事务
                                            TransactionStatus status = platformTransactionManager
                                                    .getTransaction(TransactionDefinition.withDefaults());
                                            try {
                                                accountMapper.upDate(fromId, fromMoney);
                                                int i = 1 / 0;
                                                accountMapper.upDate(destId, destMoney);
                                            }catch (Exception e) {
                                                // 事务的回滚
                                                platformTransactionManager.rollback(status);
                                                e.printStackTrace();
                                            }
                                            // 提交事务并关闭
                                            platformTransactionManager.commit(status);
                                            return 0;
                                        }
                                    

                                    TransactionTemplate

                                    • 事务的模板,采用事务模板提供的方法来使用事务
                                    • 对上面事务的传播行为做一系列的封装
                                    • 下图的绿色是需要写的业务代码

                                      13

                                      eg:

                                      • config目录下的AppConfiguration注册组件
                                        @Bean
                                        public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
                                            TransactionTemplate transactionTemplate = new TransactionTemplate();
                                            transactionTemplate.setTransactionManager(transactionManager);
                                            return transactionTemplate;
                                        }
                                        
                                        • service目录下
                                          @Service
                                          public class AccountServiceImpl implements AccountService {
                                              @Autowired
                                              AccountMapper accountMapper;
                                              @Autowired
                                              TransactionTemplate transactionTemplate;
                                              @Override
                                              public int transfer(Integer fromId, Integer destId, Double money) {
                                                  Double fromMoney = accountMapper.selectByPrimaryKey(fromId) - money;
                                                  Double destMoney = accountMapper.selectByPrimaryKey(destId) + money;
                                                  TransactionCallback transactionCallback = new TransactionCallback() {
                                                      @Override
                                                      public Object doInTransaction(TransactionStatus transactionStatus) {
                                                          accountMapper.upDate(fromId, fromMoney);
                                                          int i = 1 / 0;
                                                          accountMapper.upDate(destId, destMoney);
                                                          return null;
                                                      }
                                                  };
                                                  transactionTemplate.execute(transactionCallback);
                                                  return 0;
                                              }
                                          }
                                          

                                          Transactional注解

                                          • 采用AOP的方式给容器的组件生成代理对象
                                          • @Transactional注解的ElementType为TYPE和METHOD,意味着可以写在类上或方法上
                                            @Target({ElementType.TYPE, ElementType.METHOD})
                                            @Retention(RetentionPolicy.RUNTIME)
                                            @Inherited
                                            @Documented
                                            public @interface Transactional {
                                                @AliasFor("transactionManager")
                                                String value() default "";
                                                @AliasFor("value")
                                                String transactionManager() default "";
                                                Propagation propagation() default Propagation.REQUIRED;
                                                Isolation isolation() default Isolation.DEFAULT;
                                                int timeout() default -1;
                                                boolean readOnly() default false;
                                                Class
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]