Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务
DataSource 配置
package com.cheng.dynamic.config; import java.util.Properties; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment; @Configuration
public class DataSourceConfig {
@Autowired
private Environment env; @Bean(name = "primaryDS")
@Primary
public DataSource primaryDataSource() throws Exception{
AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
ds.setUniqueResourceName("primaryRN");
ds.setPoolSize(5);
ds.setXaProperties(build("cheng.primary.datasource."));
return ds;
} @Bean(name = "secondaryDS")
public DataSource dataSource() throws Exception{
AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
ds.setUniqueResourceName("secondaryRN");
ds.setPoolSize(5);
ds.setXaProperties(build("cheng.secondary.datasource."));
return ds;
} private Properties build(String prefix) {
Properties prop = new Properties();
prop.put("url", env.getProperty(prefix + "url"));
prop.put("username", env.getProperty(prefix + "username"));
prop.put("password", env.getProperty(prefix + "password"));
prop.put("driverClassName", env.getProperty(prefix + "driverClassName")); return prop;
}
}
JtaTransactionManagerConfig
package com.cheng.dynamic.config; import javax.transaction.UserTransaction; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.jta.JtaTransactionManager; import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager; @Configuration
public class JtaTransactionManagerConfig {
@Bean(name = "xatx")
public JtaTransactionManager regTransactionManager () {
UserTransactionManager userTransactionManager = new UserTransactionManager();
UserTransaction userTransaction = new UserTransactionImp();
return new JtaTransactionManager(userTransaction, userTransactionManager);
}
}
RepositoryPrimaryConfig
package com.cheng.dynamic.config; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
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.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Configuration
@MapperScan(basePackages = "com.cheng.dynamic.repository.primary", sqlSessionTemplateRef = "sqlSessionTemplatePrimary")
public class RepositoryPrimaryConfig {
@Autowired
private Environment env;
@Autowired
@Qualifier("primaryDS")
private DataSource primaryDS; @Bean(name="sqlSessionFactoryPrimary")
@Primary
public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception{
SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
fb.setDataSource(primaryDS);
fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));//指定基包
fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));//指定xml文件位置
return fb.getObject();
} @Bean(name = "sqlSessionTemplatePrimary")
@Primary
public SqlSessionTemplate sqlSessionTemplatePrimary(@Qualifier("sqlSessionFactoryPrimary") SqlSessionFactory sqlSessionFactory) throws Exception {
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
return sqlSessionTemplate;
}
}
RepositorySecondaryConfig
package com.cheng.dynamic.config; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
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.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Configuration
@MapperScan(basePackages = "com.cheng.dynamic.repository.secondary", sqlSessionTemplateRef = "sqlSessionTemplateSecondary")
public class RepositorySecondaryConfig {
@Autowired
private Environment env;
@Autowired
@Qualifier("secondaryDS")
private DataSource secondaryDS; @Bean(name="sqlSessionFactorySecondary")
public SqlSessionFactory sqlSessionFactorySecondary() throws Exception{
SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
fb.setDataSource(secondaryDS);
fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage2"));//指定基包
fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations2")));//指定xml文件位置
return fb.getObject();
} @Bean(name = "sqlSessionTemplateSecondary")
public SqlSessionTemplate sqlSessionTemplateSecondary(@Qualifier("sqlSessionFactorySecondary") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
Test1Service
package com.cheng.dynamic.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import com.cheng.dynamic.entity.Test1;
import com.cheng.dynamic.entity.Test2;
import com.cheng.dynamic.repository.primary.Test1Dao; @Service
@Transactional
public class Test1Service {
@Autowired
private Test1Dao test1Dao;
@Autowired
private Test2Service test2Service; public void test(){
System.out.println(test1Dao);
} public void add(Test1 t){
System.out.println(test1Dao.add(t));
System.out.println(t.getId());
} public void save(){
Test1 t1 = new Test1();
t1.setName("t1");
add(t1);
// System.out.println(1/0);
Test2 t2 = new Test2();
t2.setName("t2");
test2Service.add(t2);
}
}
测试类
package com.cheng.dynamic.service; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional; @RunWith(SpringRunner.class)
@SpringBootTest()
@Transactional(transactionManager = "xatx")
@Rollback(false)
public class Test1ServiceTest {
@Autowired
private Test1Service test1Service;
@Test
public void testTest() throws Exception {
test1Service.save();
} }
druid监控配置
package com.cheng.dynamic.config; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter; @Configuration
public class DruidConfig {
@Bean
public ServletRegistrationBean<StatViewServlet> druidServlet() {
ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*"); //控制台管理用户,加入下面2行 进入druid后台就需要登录
//servletRegistrationBean.addInitParameter("loginUsername", "admin");
//servletRegistrationBean.addInitParameter("loginPassword", "admin");
return servletRegistrationBean;
} @Bean
public FilterRegistrationBean<WebStatFilter> filterRegistrationBean() {
FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
filterRegistrationBean.addInitParameter("profileEnable", "true");
return filterRegistrationBean;
} @Bean
public StatFilter statFilter(){
StatFilter statFilter = new StatFilter();
statFilter.setLogSlowSql(true); //slowSqlMillis用来配置SQL慢的标准,执行时间超过slowSqlMillis的就是慢。
statFilter.setMergeSql(true); //SQL合并配置
statFilter.setSlowSqlMillis(1000);//slowSqlMillis的缺省值为3000,也就是3秒。
return statFilter;
} @Bean
public WallFilter wallFilter(){
WallFilter wallFilter = new WallFilter();
//允许执行多条SQL
WallConfig config = new WallConfig();
config.setMultiStatementAllow(true);
wallFilter.setConfig(config);
return wallFilter;
}
}
完整代码:https://github.com/lucheng/jta.git
其它:
SpringBoot 多数据源配置 https://github.com/lucheng/dynamic.git
SpringBoot 多数据源 + 动态数据源配置:https://github.com/lucheng/dynamicDatasource.git
Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务的更多相关文章
- Springboot+Atomikos+Jpa+Mysql实现JTA分布式事务
1 前言 之前整理了一个spring+jotm实现的分布式事务实现,但是听说spring3.X后不再支持jotm了,jotm也有好几年没更新了,所以今天整理springboot+Atomikos+jp ...
- spring+jotm+ibatis+mysql实现JTA分布式事务
1 环境 1.1 软件环境 spring-framework-2.5.6.SEC01-with-dependencies.zip ibatis-2.3.4 ow2-jotm-dist-2.1.4-b ...
- 使用Atomikos Transactions Essentials实现多数据源JTA分布式事务--转载
原文:http://www.ite/topic/122700 9.17 update:使用NonXADataSourceBean. Mysql在5.0版本和Connecter/J5.0版本后提供了XA ...
- Spring 3.0 + Atomikos构建jta分布式事务
Spring3.0已经不再支持jtom了,不过我们可以用第三方开源软件atomikos(http://www.atomikos.com/)来实现.Atomikos是目前在分布式事务管理中做得相当不错的 ...
- atomikos实现多数据源支持分布式事务管理(spring、tomcat、JTA)
原文链接:http://iteye.blog.163.com/blog/static/1863080962012102945116222/ Atomikos TransactionsEssenti ...
- JTA 分布式事务
什么是JTA - 2009-07-25 18:31:06| 分类: 技术文章|举报|字号 订阅 什么是JTA? Java Transaction API(Java事务API) (JTA)Ja ...
- springboot+atomikos+druid 数据库连接失效分析
一.起因 最近查看系统的后台日志,经常发现这样的报错信息:The last package successfully received from the server was 40802382 mil ...
- SpringBoot整合mybatis多数据源,支持分布式事务
编码工具:IDEA SpringBoot版本:2.0.1 JDK版本:1.8 1.使用IDEA构建一个Maven工程 ,添加依赖: <?xml version="1.0" e ...
- j2ee中spring的分布式事务实现及解决方案
1 java事务类型 Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供 ...
随机推荐
- eggjs 框架代理调试 SELF_SIGNED_CERT_IN_CHAIN 报错解决方案
eggjs 中的 this.ctx.curl 可以发起一个请求,配置 proxy 可以很方面的通过接口进行问题定位.代理方式如下: 1.开启 egg-development-proxyagent ,配 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储模式
前言 1.@LearningCoding 小伙伴关于用Sqlsugar在mysql数据库上的研究成果: sqlsugarcore支持mysql等数据库,在DbContext里面只需要设置dbtype为 ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单
前言 哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交 ...
- 【Caffe篇】--Caffe solver层从初始到应用
一.前述 solve主要是定义求解过程,超参数的 二.具体 #往往loss function是非凸的,没有解析解,我们需要通过优化方法来求解. #caffe提供了六种优化算法来求解最优参数,在solv ...
- service相关
本篇仍以问题为驱动 一.什么时Service? Service是Android程序中四大基础组件之一,它和Activity一样都是Context的子类,只不过它没有UI界面,是在后台运行的组件.Ser ...
- 【Python3爬虫】为什么你的博客没人看呢?
我相信对于很多爱好和习惯写博客的人来说,如果自己的博客有很多人阅读和评论的话,自己会非常开心,但是你发现自己用心写的博客却没什么人看,多多少少会觉得有些伤心吧?我们今天就来看一下为什么你的博客没人看呢 ...
- [翻译] 对正在使用EF6x开发人员的一些话
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- API接口通讯参数规范
通常在很多的公司里面,对于接口的返回值没做太大规范,所以会比较常看到各个项目各自定义随意的返回值,比如以下情况: 1. 直接返回bool值(True或者False) 2. 返回void,只要不是异常信 ...
- Asp.Net Core 轻松学-利用文件监视进行快速测试开发
前言 在进行 Asp.Net Core 应用程序开发过程中,通常的做法是先把业务代码开发完成,然后建立单元测试,最后进入本地系统集成测试:在这个过程中,程序员的大部分时间几乎都花费在开发.运行 ...
- Spring Cloud Alibaba 新版本发布:众多期待内容整合打包加入!
在Nacos 1.0.0 Release之后,Spring Cloud Alibaba也终于发布了最新的版本.该版本距离上一次发布,过去了整整4个月!下面就随我一起看看,这个大家期待已久的版本都有哪些 ...