zoukankan      html  css  js  c++  java
  • SpringBoot事物管理器

    一、springboot整合事物管理

     springboot默认集成事物,只主要在方法上加上@Transactional即可

    二、SpringBoot分布式事物管理

    使用springboot+jta+atomikos 分布式事物管理

      1、pom文件

     <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-parent</artifactId>
            <version>2.0.6.RELEASE</version>
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
            <!--mybatis起步依赖-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.1.1</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!--druid 依赖-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
            <!--aop-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
            <!--atomikos依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jta-atomikos</artifactId>
            </dependency>
        </dependencies>
    

     2、application.properties信息

    # Mysql 1
    mysql.datasource.test.url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
    mysql.datasource.test.username = root
    mysql.datasource.test.password = root
    
    mysql.datasource.test.minPoolSize = 3
    mysql.datasource.test.maxPoolSize = 25
    mysql.datasource.test.maxLifetime = 20000
    mysql.datasource.test.borrowConnectionTimeout = 30
    mysql.datasource.test.loginTimeout = 30
    mysql.datasource.test.maintenanceInterval = 60
    mysql.datasource.test.maxIdleTime = 60
    mysql.datasource.test.testQuery = select 1
    
    
    # Mysql 2
    mysql.datasource.test2.url =jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
    mysql.datasource.test2.username =root
    mysql.datasource.test2.password =root
    
    mysql.datasource.test2.minPoolSize = 3
    mysql.datasource.test2.maxPoolSize = 25
    mysql.datasource.test2.maxLifetime = 20000
    mysql.datasource.test2.borrowConnectionTimeout = 30
    mysql.datasource.test2.loginTimeout = 30
    mysql.datasource.test2.maintenanceInterval = 60
    mysql.datasource.test2.maxIdleTime = 60
    mysql.datasource.test2.testQuery = select 1

     3、创建多数据源

    @Configuration
    // basePackages 最好分开配置 如果放在同一个文件夹可能会报错
    @MapperScan(basePackages = "com.itmayiedu.test1", sqlSessionTemplateRef = "testSqlSessionTemplate")
    public class TestMyBatisConfig1 {
    
        // 配置数据源
        @Primary
        @Bean(name = "testDataSource")
        public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
            MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
            mysqlXaDataSource.setUrl(testConfig.getUrl());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
            mysqlXaDataSource.setPassword(testConfig.getPassword());
            mysqlXaDataSource.setUser(testConfig.getUsername());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
    
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(mysqlXaDataSource);
            xaDataSource.setUniqueResourceName("testDataSource");
    
            xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
            xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
            xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
            xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
            xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
            xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
            xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
            xaDataSource.setTestQuery(testConfig.getTestQuery());
            return xaDataSource;
        }
    
        @Primary
        @Bean(name = "testSqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            return bean.getObject();
        }
    
        @Primary
        @Bean(name = "testSqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }
    // basePackages 最好分开配置 如果放在同一个文件夹可能会报错
    @Configuration
    @MapperScan(basePackages = "com.itmayiedu.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
    public class TestMyBatisConfig2 {
    
        // 配置数据源
        @Bean(name = "test2DataSource")
        public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
            MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
            mysqlXaDataSource.setUrl(testConfig.getUrl());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
            mysqlXaDataSource.setPassword(testConfig.getPassword());
            mysqlXaDataSource.setUser(testConfig.getUsername());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
    
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(mysqlXaDataSource);
            xaDataSource.setUniqueResourceName("test2DataSource");
    
            xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
            xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
            xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
            xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
            xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
            xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
            xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
            xaDataSource.setTestQuery(testConfig.getTestQuery());
            return xaDataSource;
        }
    
        @Bean(name = "test2SqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            return bean.getObject();
        }
    
        @Bean(name = "test2SqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }

    4、启动加载配置

    @EnableConfigurationProperties(value = { DBConfig1.class, DBConfig2.class })

    5、controller类

    @RestController
    public class MybatisMultilDataSourceController {
        @Autowired
        private UserServiceTest01 userServiceTest01;
        @Autowired
        private UserServiceTest02 userServiceTest02;
    
        @RequestMapping("/insertUserTest1")
        public Integer insertUserTest1(String name, Integer age) {
            return userServiceTest01.insertUser(name, age);
        }
    
        @RequestMapping("/insertUserTest2")
        public Integer insertUserTest2(String name, Integer age) {
            return userServiceTest02.insertUser(name, age);
        }
    
        @RequestMapping("/insertUserTest01AndTest02")
        public int insertUserTest01AndTest02(String name, Integer age) {
            return userServiceTest02.insertUserTest01AndTest02(name, age);
        }

    6、多个Mapper接口

    根据包区分

    public interface UserMapperTest01 {
        
    
        // 添加
        @Insert("INSERT INTO USERS(NAME, AGE) VALUES(#{name}, #{age})")
        int insert(@Param("name") String name, @Param("age") Integer age);
    }
    public interface UserMapperTest02 {
        
    
        // 添加
        @Insert("INSERT INTO USERS(NAME, AGE) VALUES(#{name}, #{age})")
        int insert(@Param("name") String name, @Param("age") Integer age);
    }

    7、多个service

    根据包区分

    @Service
    @Slf4j
    public class UserServiceTest02 {
        @Autowired
        private UserMapperTest02 userMapperTest02;
        @Autowired
        private UserMapperTest01 userMapperTest01;
    
        @Transactional(transactionManager = "test2TransactionManager")
        public int insertUser(String name, Integer age) {
            int insertUserResult = userMapperTest02.insert(name, age);
            log.info("######insertUserResult:{}##########", insertUserResult);
            // 怎么样验证事务开启成功!~
            int i = 1 / age;
            return insertUserResult;
        }
    
        @Transactional()
        public int insertUserTest01AndTest02(String name, Integer age) {
            // 传统分布式事务解决方案 jta+atomikos 注册同一个全局事务中
            // 第一个数据源
            int insertUserResult01 = userMapperTest01.insert(name, age);
            // 第二个数据源
            int insertUserResult02 = userMapperTest02.insert(name, age);
            int i = 1 / 0;
            int result = insertUserResult01 + insertUserResult02;
            // test01入库 test02回滚
            return result;
        }
    
    }
    @Service
    @Slf4j
    public class UserServiceTest01 {
        @Autowired
        private UserMapperTest01 userMapperTest01;
    
        @Transactional(transactionManager = "test1TransactionManager")
        public int insertUser(String name, Integer age) {
            int insertUserResult = userMapperTest01.insert(name, age);
            log.info("######insertUserResult:{}##########", insertUserResult);
            int i = 1 / age;
            // 怎么样验证事务开启成功!~
            return insertUserResult;
        }
    
    }

    第三 多数据源分包方式事物

    1、controller类

    @RestController
    public class MybatisMultilDataSourceController {
        @Autowired
        private UserServiceTest01 userServiceTest01;
        @Autowired
        private UserServiceTest02 userServiceTest02;
    
        @RequestMapping("/insertUserTest1")
        public Integer insertUserTest1(String name, Integer age) {
            return userServiceTest01.insertUser(name, age);
        }
    
        @RequestMapping("/insertUserTest2")
        public Integer insertUserTest2(String name, Integer age) {
            return userServiceTest02.insertUser(name, age);
        }
    }

    2、service类

    根据包区分

    @Service
    @Slf4j
    public class UserServiceTest01 {
        @Autowired
        private UserMapperTest01 userMapperTest01;
    
        @Transactional(transactionManager = "test1TransactionManager")
        public int insertUser(String name, Integer age) {
            int insertUserResult = userMapperTest01.insert(name, age);
            log.info("######insertUserResult:{}##########", insertUserResult);
            int i = 1 / age;
            // 怎么样验证事务开启成功!~
            return insertUserResult;
        }
    
    }
    @Service
    @Slf4j
    public class UserServiceTest02 {
        @Autowired
        private UserMapperTest02 userMapperTest02;
    
        @Transactional(transactionManager = "test2TransactionManager")
        public int insertUser(String name, Integer age) {
            int insertUserResult = userMapperTest02.insert(name, age);
            log.info("######insertUserResult:{}##########", insertUserResult);
            // 怎么样验证事务开启成功!~
            int i = 1 / age;
            return insertUserResult;
        }
    
    }

    3、mapper接口

    根据包区分

    public interface UserMapperTest01 {
        // 查询语句
        @Select("SELECT * FROM USERS WHERE NAME = #{name}")
        User findByName(@Param("name") String name);
    
        // 添加
        @Insert("INSERT INTO USERS(NAME, AGE) VALUES(#{name}, #{age})")
        int insert(@Param("name") String name, @Param("age") Integer age);
    }
    public interface UserMapperTest01 2{
        // 查询语句
        @Select("SELECT * FROM USERS WHERE NAME = #{name}")
        User findByName(@Param("name") String name);
    
        // 添加
        @Insert("INSERT INTO USERS(NAME, AGE) VALUES(#{name}, #{age})")
        int insert(@Param("name") String name, @Param("age") Integer age);
    }

    4、创建多个数据源

    @Configuration // 注册到springboot容器中
    @MapperScan(basePackages = "com.itmayiedu.test01", sqlSessionFactoryRef = "test1SqlSessionFactory")
    public class DataSource1Config {
    
     
        @Bean(name = "test1DataSource")
        @ConfigurationProperties(prefix = "spring.datasource.test1")
        public DataSource testDataSource() {
            return DataSourceBuilder.create().build();
        }
    
    
        @Bean(name = "test1SqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            // bean.setMapperLocations(
            // new
            // PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
            return bean.getObject();
        }
    
    
        @Bean(name = "test1TransactionManager")
        public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        @Bean(name = "test1SqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    
    }
    @Configuration // 注册到springboot容器中
    @MapperScan(basePackages = "com.itmayiedu.test02", sqlSessionFactoryRef = "test2SqlSessionFactory")
    public class DataSource2Config {
    
    
        @Bean(name = "test2DataSource")
        @ConfigurationProperties(prefix = "spring.datasource.test2")
        public DataSource testDataSource() {
            return DataSourceBuilder.create().build();
        }
    
    
        @Bean(name = "test2SqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            // bean.setMapperLocations(
            // new
            // PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
            return bean.getObject();
        }
    
        @Bean(name = "test2TransactionManager")
        public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        @Bean(name = "test2SqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    
    }

    5、application.properties

    ###datasource1
    spring.datasource.test1.driver-class-name = com.mysql.jdbc.Driver
    spring.datasource.test1.jdbc-url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
    spring.datasource.test1.username = root
    spring.datasource.test1.password = root
    ###datasource2
    spring.datasource.test2.driver-class-name = com.mysql.jdbc.Driver
    spring.datasource.test2.jdbc-url = jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
    spring.datasource.test2.username = root
    spring.datasource.test2.password = root
  • 相关阅读:
    idea gson使用
    spring对象工具类
    java反射判断对象空字段
    说说沟通乱这件事
    RandomShuffleQueue
    学习材料
    python异常处理
    tensorboard基础使用
    深度学习——特殊应用:人脸识别和神经风格转换[13]
    深度学习——目标检测[12]
  • 原文地址:https://www.cnblogs.com/cxyyh/p/10631929.html
Copyright © 2011-2022 走看看