• Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务


    DataSource 配置
     1 package com.cheng.dynamic.config;
     2 
     3 import java.util.Properties;
     4 
     5 import javax.sql.DataSource;
     6 
     7 import org.springframework.beans.factory.annotation.Autowired;
     8 import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
     9 import org.springframework.context.annotation.Bean;
    10 import org.springframework.context.annotation.Configuration;
    11 import org.springframework.context.annotation.Primary;
    12 import org.springframework.core.env.Environment;
    13 
    14 @Configuration
    15 public class DataSourceConfig {
    16     @Autowired
    17     private Environment env;
    18     
    19     @Bean(name = "primaryDS")
    20     @Primary
    21     public DataSource primaryDataSource() throws Exception{
    22         AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
    23         ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
    24         ds.setUniqueResourceName("primaryRN");
    25         ds.setPoolSize(5);
    26         ds.setXaProperties(build("cheng.primary.datasource."));
    27         return ds;
    28     }
    29     
    30     @Bean(name = "secondaryDS")
    31     public DataSource dataSource() throws Exception{
    32         AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
    33         ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
    34         ds.setUniqueResourceName("secondaryRN");
    35         ds.setPoolSize(5);
    36         ds.setXaProperties(build("cheng.secondary.datasource."));
    37         return ds;
    38     }
    39     
    40     private Properties build(String prefix) {
    41         Properties prop = new Properties();
    42         prop.put("url", env.getProperty(prefix + "url"));
    43         prop.put("username", env.getProperty(prefix + "username"));
    44         prop.put("password", env.getProperty(prefix + "password"));
    45         prop.put("driverClassName", env.getProperty(prefix + "driverClassName"));
    46 
    47         return prop;
    48     }
    49 }

    JtaTransactionManagerConfig

     1 package com.cheng.dynamic.config;
     2 
     3 import javax.transaction.UserTransaction;
     4 
     5 import org.springframework.context.annotation.Bean;
     6 import org.springframework.context.annotation.Configuration;
     7 import org.springframework.transaction.jta.JtaTransactionManager;
     8 
     9 import com.atomikos.icatch.jta.UserTransactionImp;
    10 import com.atomikos.icatch.jta.UserTransactionManager;
    11 
    12 @Configuration
    13 public class JtaTransactionManagerConfig {
    14     @Bean(name = "xatx")
    15     public JtaTransactionManager regTransactionManager () {
    16         UserTransactionManager userTransactionManager = new UserTransactionManager();
    17         UserTransaction userTransaction = new UserTransactionImp();
    18         return new JtaTransactionManager(userTransaction, userTransactionManager);
    19     }
    20 }

    RepositoryPrimaryConfig

     1 package com.cheng.dynamic.config;
     2 
     3 import javax.sql.DataSource;
     4 
     5 import org.apache.ibatis.session.SqlSessionFactory;
     6 import org.mybatis.spring.SqlSessionFactoryBean;
     7 import org.mybatis.spring.SqlSessionTemplate;
     8 import org.mybatis.spring.annotation.MapperScan;
     9 import org.springframework.beans.factory.annotation.Autowired;
    10 import org.springframework.beans.factory.annotation.Qualifier;
    11 import org.springframework.context.annotation.Bean;
    12 import org.springframework.context.annotation.Configuration;
    13 import org.springframework.context.annotation.Primary;
    14 import org.springframework.core.env.Environment;
    15 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    16 
    17 @Configuration
    18 @MapperScan(basePackages = "com.cheng.dynamic.repository.primary", sqlSessionTemplateRef  = "sqlSessionTemplatePrimary")
    19 public class RepositoryPrimaryConfig {
    20     @Autowired
    21     private Environment env;
    22     @Autowired 
    23     @Qualifier("primaryDS")
    24     private DataSource primaryDS;
    25     
    26     @Bean(name="sqlSessionFactoryPrimary")
    27     @Primary
    28     public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception{
    29         SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
    30         fb.setDataSource(primaryDS);
    31         fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));//指定基包
    32         fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));//指定xml文件位置
    33         return fb.getObject();
    34     }
    35     
    36     @Bean(name = "sqlSessionTemplatePrimary")
    37     @Primary
    38     public SqlSessionTemplate sqlSessionTemplatePrimary(@Qualifier("sqlSessionFactoryPrimary") SqlSessionFactory sqlSessionFactory) throws Exception {
    39         SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
    40         return sqlSessionTemplate;
    41     }
    42 }

    RepositorySecondaryConfig

     1 package com.cheng.dynamic.config;
     2 
     3 import javax.sql.DataSource;
     4 
     5 import org.apache.ibatis.session.SqlSessionFactory;
     6 import org.mybatis.spring.SqlSessionFactoryBean;
     7 import org.mybatis.spring.SqlSessionTemplate;
     8 import org.mybatis.spring.annotation.MapperScan;
     9 import org.springframework.beans.factory.annotation.Autowired;
    10 import org.springframework.beans.factory.annotation.Qualifier;
    11 import org.springframework.context.annotation.Bean;
    12 import org.springframework.context.annotation.Configuration;
    13 import org.springframework.core.env.Environment;
    14 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    15 
    16 @Configuration
    17 @MapperScan(basePackages = "com.cheng.dynamic.repository.secondary", sqlSessionTemplateRef  = "sqlSessionTemplateSecondary")
    18 public class RepositorySecondaryConfig {
    19     @Autowired
    20     private Environment env;
    21     @Autowired 
    22     @Qualifier("secondaryDS")
    23     private DataSource secondaryDS;
    24 
    25     @Bean(name="sqlSessionFactorySecondary")
    26     public SqlSessionFactory sqlSessionFactorySecondary() throws Exception{
    27         SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
    28         fb.setDataSource(secondaryDS);
    29         fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage2"));//指定基包
    30         fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations2")));//指定xml文件位置
    31         return fb.getObject();
    32     }
    33     
    34     @Bean(name = "sqlSessionTemplateSecondary")
    35     public SqlSessionTemplate sqlSessionTemplateSecondary(@Qualifier("sqlSessionFactorySecondary") SqlSessionFactory sqlSessionFactory) throws Exception {
    36         return new SqlSessionTemplate(sqlSessionFactory);
    37     }
    38 }

    Test1Service

     1 package com.cheng.dynamic.service;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.stereotype.Service;
     5 import org.springframework.transaction.annotation.Transactional;
     6 
     7 import com.cheng.dynamic.entity.Test1;
     8 import com.cheng.dynamic.entity.Test2;
     9 import com.cheng.dynamic.repository.primary.Test1Dao;
    10 
    11 @Service
    12 @Transactional
    13 public class Test1Service {
    14     @Autowired
    15     private Test1Dao test1Dao;
    16     @Autowired
    17     private Test2Service test2Service;
    18     
    19     public void test(){
    20         System.out.println(test1Dao);
    21     }
    22     
    23     public void add(Test1 t){
    24         System.out.println(test1Dao.add(t));
    25         System.out.println(t.getId());
    26     }
    27     
    28     public void save(){
    29         Test1 t1 = new Test1();
    30         t1.setName("t1");
    31         add(t1);
    32 //        System.out.println(1/0);
    33         Test2 t2 = new Test2();
    34         t2.setName("t2");
    35         test2Service.add(t2);
    36     }
    37 }

    测试类

     1 package com.cheng.dynamic.service;
     2 
     3 import org.junit.Test;
     4 import org.junit.runner.RunWith;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.boot.test.context.SpringBootTest;
     7 import org.springframework.test.annotation.Rollback;
     8 import org.springframework.test.context.junit4.SpringRunner;
     9 import org.springframework.transaction.annotation.Transactional;
    10 
    11 @RunWith(SpringRunner.class)
    12 @SpringBootTest()
    13 @Transactional(transactionManager = "xatx")
    14 @Rollback(false)
    15 public class Test1ServiceTest {
    16     @Autowired
    17     private Test1Service test1Service;
    18     @Test
    19     public void testTest() throws Exception {
    20         test1Service.save();
    21     }
    22 
    23 }

    druid监控配置

     1 package com.cheng.dynamic.config;
     2 
     3 import org.springframework.boot.web.servlet.FilterRegistrationBean;
     4 import org.springframework.boot.web.servlet.ServletRegistrationBean;
     5 import org.springframework.context.annotation.Bean;
     6 import org.springframework.context.annotation.Configuration;
     7 
     8 import com.alibaba.druid.filter.stat.StatFilter;
     9 import com.alibaba.druid.support.http.StatViewServlet;
    10 import com.alibaba.druid.support.http.WebStatFilter;
    11 import com.alibaba.druid.wall.WallConfig;
    12 import com.alibaba.druid.wall.WallFilter;
    13 
    14 @Configuration
    15 public class DruidConfig {
    16      @Bean
    17         public ServletRegistrationBean<StatViewServlet> druidServlet() {
    18             ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
    19 
    20             //控制台管理用户,加入下面2行 进入druid后台就需要登录
    21             //servletRegistrationBean.addInitParameter("loginUsername", "admin");
    22             //servletRegistrationBean.addInitParameter("loginPassword", "admin");
    23             return servletRegistrationBean;
    24         }
    25 
    26         @Bean
    27         public FilterRegistrationBean<WebStatFilter> filterRegistrationBean() {
    28             FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>();
    29             filterRegistrationBean.setFilter(new WebStatFilter());
    30             filterRegistrationBean.addUrlPatterns("/*");
    31             filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
    32             filterRegistrationBean.addInitParameter("profileEnable", "true");
    33             return filterRegistrationBean;
    34         }
    35 
    36         @Bean
    37         public StatFilter statFilter(){
    38             StatFilter statFilter = new StatFilter();
    39             statFilter.setLogSlowSql(true); //slowSqlMillis用来配置SQL慢的标准,执行时间超过slowSqlMillis的就是慢。
    40             statFilter.setMergeSql(true); //SQL合并配置
    41             statFilter.setSlowSqlMillis(1000);//slowSqlMillis的缺省值为3000,也就是3秒。
    42             return statFilter;
    43         }
    44 
    45         @Bean
    46         public WallFilter wallFilter(){
    47             WallFilter wallFilter = new WallFilter();
    48             //允许执行多条SQL
    49             WallConfig config = new WallConfig();
    50             config.setMultiStatementAllow(true);
    51             wallFilter.setConfig(config);
    52             return wallFilter;
    53         }
    54 }

    完整代码:https://github.com/lucheng/jta.git

    其它:

    SpringBoot 多数据源配置 https://github.com/lucheng/dynamic.git

    SpringBoot 多数据源 + 动态数据源配置:https://github.com/lucheng/dynamicDatasource.git

  • 相关阅读:
    centos 6,7 上cgroup资源限制使用举例
    redis sentinel哨兵的使用
    redis发布-订阅
    Golang cpu的使用设置--GOMAXPROCS
    Golang 端口复用测试
    Golang client绑定本地IP和端口
    Go并发控制--context的使用
    Go 并发控制--WaitGroup的使用
    go thrift报错问题--WriteStructEnd
    secureCRT上传本地文件到虚拟机
  • 原文地址:https://www.cnblogs.com/tusheng/p/9077309.html
Copyright © 2020-2023  润新知