springboot多数据库及分布式事务配置

1、导入相应的jar包依赖

<!-- 集成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>

<!-- 分布式事务管理 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>

2、配置多数据源

  2.1 在application.xml中配置多数据源的连接

spring: 
 datasource: 
  test1: 
   url: jdbc:mysql://localhost:3306/test
   username: root
   password: root
   driver-class-name: com.mysql.jdbc.Driver
   testQuery: select 1
  test2: 
   url: jdbc:mysql://localhost:3306/test1
   username: root
   password: root
   driver-class-name: com.mysql.jdbc.Driver
   testQuery: select 1
mybatis:
  mapper-locations: classpath:mapping/*.xml 

  2.2 创建多数据库的连接信息配置类

@ConfigurationProperties(prefix="spring.datasource.test1")
@Primary
public class DB1Config {
    
    private String url;
    
    private String username;
    
    private String password;
    
    private String testQuery;

    public String getUrl() {
        return url;
    }

  ...添加get和set方法,如果多个数据源要配置多个
}

  2.3 创建多数据源的配置类,将不同的数据源交给jta的atomikos进行统一管理(多个数据源配置多个这样的文件)

@Configuration//注册到spring boot容器中
@MapperScan(basePackages="com.beifeng.hadoop.spring.boot.dao.jta.test1",sqlSessionFactoryRef="jtaTest1SqlSessionFactory")
public class JtaDataSource1Config {

    @Bean(name="jtaTest1DataSource")
    @Primary//一个项目中只指定一个数据源为主数据源
    public DataSource testDataSource(DB1Config db1Config){
        MysqlXADataSource dataSource=new MysqlXADataSource();
        dataSource.setUrl(db1Config.getUrl());
        dataSource.setUser(db1Config.getUsername());
        dataSource.setPassword(db1Config.getPassword());
        dataSource.setPinGlobalTxToPhysicalConnection(true);
        //将该数据源叫个atomikos进行统一管理
        AtomikosDataSourceBean atomikosDataSource=new AtomikosDataSourceBean();
        atomikosDataSource.setXaDataSource(dataSource);
        atomikosDataSource.setUniqueResourceName("jtaTest1DataSource");
        atomikosDataSource.setTestQuery(db1Config.getTestQuery());
        return atomikosDataSource;
    }
    
    @Bean(name="jtaTest1SqlSessionFactory")
    @Primary
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("jtaTest1DataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean=new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }
    
    @Bean(name="jtaTest1SqlSessionTemplate")
    @Primary
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("jtaTest1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

  2.4 在service中进行声明式事务配置

@Service
public class Test1JtaUserService {
    
    @Autowired//引入不同的数据源
    private JtaUser1Dao jtaUser1Dao;
    
    @Autowired
    private JtaUser2Dao jtaUser2Dao;
    
    @Transactional//声明式事务
    public void insertJtaUser(String name,Integer age) {
        jtaUser1Dao.insertUser(name, age);
        jtaUser2Dao.insertUser(name, age);
        int a=1/0;//如果出现异常,分布式事务会同时回滚
    }
    
}

  2.5 在启动类中声明多数据源的配置

@SpringBootApplication
@MapperScan("com.beifeng.hadoop.spring.boot.dao")//指定mybatis的dao扫包路径
@EnableConfigurationProperties(value={DB1Config.class,DB2Config.class})//指定多数据源的配置
public class App {
    
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

3 aop切面编程

@Aspect
@Component
public class WebLogAspect {

    private Logger logger=LoggerFactory.getLogger(WebLogAspect.class);
    
    private Long startTime;
    
    @Pointcut("execution(public * com.beifeng.hadoop.spring.boot.controller..*.*(..))")
    public void webLog() {
        
    }
    
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        logger.info("==============开始请求=============");
        startTime=System.currentTimeMillis(); 
        //接收到请求,记录请求内容
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest=requestAttributes.getRequest();
        logger.info("url:   "+httpServletRequest.getRequestURL());
        logger.info("http_method:    "+httpServletRequest.getMethod());
        logger.info("ip    "+httpServletRequest.getRemoteAddr());
        Enumeration<String> parameterNames = httpServletRequest.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String parameterName = (String) parameterNames.nextElement();
            logger.info("parameter:{}->{}",parameterName,httpServletRequest.getParameter(parameterName));
        }
    }
    
    @AfterReturning(returning="ret",pointcut="webLog()")
    public void doAfterReturning(Object ret) {
        //处理完请求,返回内容
        logger.info("响应结果:"+ret);
        logger.info("==============开始结束,耗时"+(System.currentTimeMillis()-startTime)+"毫秒=============");
        
    }
}

猜你喜欢

转载自www.cnblogs.com/lifeone/p/9004372.html