springBoot配置XA事务和非XA事务

事务管理器配置 

// 分布式事务管理器
	@Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
	public TransactionManager atomikosTransactionManager() throws Throwable {
		UserTransactionManager userTransactionManager = new UserTransactionManager();
		userTransactionManager.setForceShutdown(false);
		return userTransactionManager;
	}

	/**
	 * 注入事物管理器
	 * 
	 * @return
	 * @throws Throwable
	 */
	@Bean(name = "xatx")
	@DependsOn({ "userTransaction", "atomikosTransactionManager" })
	public JtaTransactionManager regTransactionManager() throws Throwable {
		TransactionManager userTransactionManager = atomikosTransactionManager();
		UserTransaction userTransaction = userTransaction();
		return new JtaTransactionManager(userTransaction, userTransactionManager);
	}

	@Bean(name = "userTransaction")
	public UserTransaction userTransaction() throws Throwable {
		UserTransactionImp userTransactionImp = new UserTransactionImp();
		userTransactionImp.setTransactionTimeout(10000);
		return userTransactionImp;
	}


	
	
   
  
    //目前业务只有BIZ需要事务
    @Bean(name = "bizTransaction")
    @Primary
    public PlatformTransactionManager bizTransaction(@Qualifier(value = "bizDataSource") DataSource dataSource) {
    	DataSourceTransactionManager manager =  new DataSourceTransactionManager();
    	manager.setDataSource(dataSource);

    	return manager;
    }

配置dataSource(需要配置XA事务的数据源需要配置两个,一个XA数据源和一个非XA事务的数据源)

 @Bean(name = "tempDataSource")
    @Autowired
    public DataSource systemDataSource(Environment env) {
    	
    	DruidDataSource ds =  new DruidDataSource();
    	build(env, "spring.datasource.druid.temp.",ds);
        return ds;

    }

    @Autowired
    @Bean(name = "bizDataSource")
    @Primary
    public DataSource businessDataSource(Environment env) {
    	
    	DruidDataSource ds =  new DruidDataSource();
    	build(env, "spring.datasource.druid.biz.",ds);
    
    
        return ds;
    }
    @Autowired
    @Bean(name = "bizXADataSource")
    @DependsOn({"xatx"})
    public AtomikosDataSourceBean bizXADataSource(Environment env) {
		AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
		DmdbXADataSource datasource;
		String prefix = "spring.datasource.druid.biz.";
		try {
			datasource = new DmdbXADataSource();
			datasource.setURL(env.getProperty(prefix + "url"));
			datasource.setPassword(env.getProperty(prefix + "password"));
			datasource.setUser(env.getProperty(prefix + "username"));
			ds.setXaDataSource(datasource);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		ds.setUniqueResourceName("bizDB");
		ds.setMinPoolSize(0);
		ds.setMaintenanceInterval(600);
		ds.setTestQuery("select 2");
		return ds;
	}
 @Autowired
    @Bean(name = "internetDataSource")

    public DataSource internetDataSource(Environment env) {
    	
       
    	DruidDataSource ds =  new DruidDataSource();
    	build(env, "spring.datasource.druid.internetdb.",ds);
        return ds;
       
    }
    @Autowired
    @Bean(name = "internetXADataSource")
    @DependsOn({"xatx"})
    public AtomikosDataSourceBean internetXADataSource(Environment env) {

        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        Properties prop = build(env, "spring.datasource.druid.internetdb.");
        ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
        ds.setUniqueResourceName("internetDB");
        ds.setMinPoolSize(0);
        ds.setXaProperties(prop);
        ds.setMaintenanceInterval(600);
        ds.setMaxLifetime(20000);
        ds.setTestQuery("select 2");
        return ds;
    }

配置sessionFactroy(XA事务和非XA事务要分包,并且不能混合使用,通过basePackages 来区分dataSource)

package com.neusoft.saca.hlwjjg.config;

import javax.sql.DataSource;

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;

@Configuration
@MapperScan(basePackages = "com.neusoft.saca.hlwjjg.biz.**.mapper", sqlSessionFactoryRef = "bizSqlSessionFactory",
        nameGenerator = MultidataApplication.SpringBeanNameGenerator.class)
public class BizDataSourceConfiguration {

    public static final Logger LOGGER = LoggerFactory.getLogger(BizDataSourceConfiguration.class);

    @Autowired
    @Qualifier("bizDataSource")
    private DataSource ds;

//    @Resource
//    private TraceSQL traceSQL;

    @Bean
    public SqlSessionFactory bizSqlSessionFactory() throws Exception {

    	 MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
         factoryBean.setDataSource(ds);

        //指定mapper xml目录
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        factoryBean.setPlugins(new PaginationInterceptor[]{new PaginationInterceptor()});
        factoryBean.setMapperLocations(resolver.getResources("classpath:mapper/biz/**/*.xml"));
       
        return factoryBean.getObject();
    }


    @Bean
    public SqlSessionTemplate bizSqlSessionTemplate() throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(bizSqlSessionFactory()); // 使用上面配置的Factory
        return template;
    }

    @Bean
    public SqlSessionTemplate bizBatchSqlSession() throws Exception {
        return new SqlSessionTemplate(bizSqlSessionFactory(), ExecutorType.BATCH);
    }
}

配置非XA事务切面

package com.neusoft.saca.hlwjjg.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import com.neusoft.saca.hlwjjg.exception.BusinessException;
@Aspect
@Configuration
public class TransactionAdviceConfig {
    private static final String AOP_POINTCUT_EXPRESSION_BIZ = "execution (* com.neusoft.saca.hlwjjg.biz.**.service..*.*(..))";
  
    @Resource(name = "bizTransaction")
    private PlatformTransactionManager bizManager;

    private static final int TX_METHOD_TIMEOUT=5;
    @Bean(name="txbizAdvice")
    public TransactionInterceptor txbizAdvice() {
        /*事务管理规则,声明具备事务管理的方法名*/
        NameMatchTransactionAttributeSource source=new NameMatchTransactionAttributeSource();
        /*只读事物、不做更新删除等*/
        /*当前存在事务就用当前的事务,当前不存在事务就创建一个新的事务*/
        RuleBasedTransactionAttribute readOnlyRule=new RuleBasedTransactionAttribute();
        /*设置当前事务是否为只读事务,true为只读*/
        readOnlyRule.setReadOnly(true);
        /* transactiondefinition 定义事务的隔离级别;
         * PROPAGATION_NOT_SUPPORTED支持当前事务,如果没有事务的话以非事务方式执行*/
        readOnlyRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
        
        RuleBasedTransactionAttribute requireRule=new RuleBasedTransactionAttribute();
        /*抛出异常后执行切点回滚*/
        List<RollbackRuleAttribute> exceptions = new ArrayList<>();
        exceptions.add(new RollbackRuleAttribute(Exception.class));
        exceptions.add(new RollbackRuleAttribute(BusinessException.class));
        requireRule.setRollbackRules(exceptions);
        /*PROPAGATION_REQUIRED:事务隔离性为1,若当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。 */
        requireRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        /*设置事务失效时间,如果超过5秒,则回滚事务*/
        requireRule.setTimeout(TX_METHOD_TIMEOUT);
        Map<String,TransactionAttribute> txMap=new HashMap<>();
 
        txMap.put("add*",requireRule);
        txMap.put("save*", requireRule);
        txMap.put("saveOrUpdate*", requireRule);
        txMap.put("insert*",requireRule);
        txMap.put("update*",requireRule);
        txMap.put("delete*",requireRule);
        txMap.put("remove*",requireRule);
        
        txMap.put("get*",readOnlyRule);
        txMap.put("check*",readOnlyRule);
        txMap.put("query*", readOnlyRule);
        txMap.put("find*", readOnlyRule);
        txMap.put("select*",readOnlyRule);
        txMap.put("list*",readOnlyRule);
        source.setNameMap(txMap);
        TransactionInterceptor txAdvice=new TransactionInterceptor(bizManager, source);
        return txAdvice;
    }

    @Bean(name="txbizAdviceAdvisor")
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION_BIZ);
        return new DefaultPointcutAdvisor(pointcut, txbizAdvice());
    }
   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值