多数据源的配置,不支持分布式事物
springboot + mybatis + druid
多数据源配置
看了别人的配置,还是觉得自己配置的比较简单。。直接看代码
这是不支持分布式事物的配置。
后面会说明,支持分布式事物的配置
springboot 启动类
package com;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.cat.common.listener.REnvContent;
import com.cat.common.listener.RSystemConfig;
/**
* 启动类注解 如果其他代码不在这个类的子目录里面需要加
*
* @ComponentScan(basePackages = { "com.cat.**", "com.smk.**","com.boot.**"})
* @ServletComponentScan
* @EnableScheduling
* @EnableAsync
* @author luoyang
*
*/
@SpringBootApplication
@EnableAutoConfiguration
@EnableTransactionManagement
@Configuration
@EnableAsync
@EnableScheduling
public class App extends SpringBootServletInitializer {
/**
* 获取系统的环境变量
*/
public static final String env_home="PUSH_HOME";
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//自定义配置,必须先初始化环境变量的位置
RSystemConfig.init(env_home);
builder.sources(App.class);
Properties p = new Properties();
String path = RSystemConfig.Home_Path + REnvContent.Application;
try {
p.load(new FileInputStream(new File(path)));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
builder.application().setDefaultProperties(p);
return builder;
}
public static void main(String[] args) throws IOException {
/*
* Properties p = new Properties(); String path =
* RSystemConfig.Home_Path + REnvContent.Application; p.load(new
* FileInputStream(new File(path))); SpringApplication app = new
* SpringApplication(App.class); app.setDefaultProperties(p);
* app.run(args);
*/
SpringApplication.run(App.class, args);
}
}
数据源1配置,mysql数据库
package com.config;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
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 org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.cat.common.mybatis.SqlSessionFactoryBean;
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages= {"com.smk.push.**.dao","com.cat.**.dao"},sqlSessionTemplateRef="userSqlSessionTemplate")
public class DruidConfig {
//MapperScan 指定当前数据源扫描的DAO包,简单的说,在com.smk.push.**.dao","com.cat.**.dao 这2个包名的所有DAO,都是使用这个mysql 数据源
//sqlSessionTemplateRef 不能为空,使用当前的sqlSessionTemplate
@Bean
public ServletRegistrationBean druidServlet() {
//druid 可视化显示
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
reg.addInitParameter("loginUsername", "luoyang");
reg.addInitParameter("loginPassword", "luoyang123456");
reg.addInitParameter("allow", "*");
reg.addInitParameter("resetEnable", "false");
return reg;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
//druid 可视化显示
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
filterRegistrationBean.addInitParameter("profileEnable", "true");
filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
filterRegistrationBean.setFilter(new WebStatFilter());
return filterRegistrationBean;
}
// 按照BeanId来拦截配置 用来bean的监控
@Bean(value = "druid-stat-interceptor")
public DruidStatInterceptor druidStatInterceptor() {
//druid 可视化显示
DruidStatInterceptor druidStatInterceptor = new DruidStatInterceptor();
return druidStatInterceptor;
}
@Bean(name="dataSource", destroyMethod = "close", initMethod="init")
@ConfigurationProperties(prefix = "spring.adatasource")
@Primary
public DataSource druidDataSource(){
//配置数据源
//ConfigurationProperties 配置再application.properties 文件中的数据库前缀
//@Primary 多数据源,一定要指定一个默认的
return new DruidDataSource();
}
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
System.out.println("sqlSessionFactory init ");
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//指定该数据源扫描对应的 mybatis 对应的配置文件。使用文件夹隔离不同的数据源
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:msq/**/*.xml"));
/*sqlSessionFactoryBean.setPlugins(new Interceptor[]{new AparamsInterceptor(),new ResultInterceptor(),
new ParameterInterceptor(),new StatementInterceptor()});*/
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory);
return template;
}
/**
* 配置事务管理器
*/
@Bean(name="smkAppTransaction")
@Primary
public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
数据源2,oracle数据库
package com.config;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.cat.common.mybatis.SqlSessionFactoryBean;
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages= {"com.smk.orc.**.dao"},sqlSessionTemplateRef="abcSqlSessionTemplate")
public class OracleDruidConfig {
@Bean(name="orcDataSource", destroyMethod = "close", initMethod="init")
@ConfigurationProperties(prefix = "spring.orc.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
@Bean(name = "orcSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("orcDataSource") DataSource dataSource) throws Exception {
System.out.println("sqlSessionFactory init ");
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:orc/**/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate abcSqlSessionTemplate(@Qualifier("orcSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory);
return template;
}
/**
* 配置事务管理器
*/
@Bean(name="orcTransaction")
public PlatformTransactionManager transactionManager(@Qualifier("orcDataSource") DataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
配置文件 application.properties
#server.contextPath=/smk_web
#server.port=8888
#spring.application.index=true
#spring.application.name=cat_boot
spring.jmx.default-domain=smk_push
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.default-property-inclusion=non_null
spring.jackson.time-zone=GMT+8
spring.mvc.view.prefix:/WEB-INF/page/
spring.mvc.view.suffix:.jsp
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
logging.config=classpath:env/env_dev/logback-spring.xml
#set it false if you don't want use dashboard.default true
#rocketmq.config.enableDashBoardCollect=true
#max file size limit
spring.http.multipart.maxFileSize=10Mb
#spring.http.multipart.maxRequestSize=10Mb
spring.adatasource.driverClassName=com.mysql.jdbc.Driver
spring.adatasource.url=jdbc:mysql://192.168.23.212:3306/smk_push?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true
#spring.datasource.url=jdbc:mysql://10.101.253.166:3306/smk_push?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true
#spring.datasource.username=smk_push
#spring.datasource.password=push96225#
spring.adatasource.username=root
spring.adatasource.password=123456
# init pool size
spring.adatasource.initialSize=5
spring.adatasource.minIdle=5
spring.adatasource.maxActive=20
# wait time out Millisecond
spring.adatasource.maxWait=60000
# check alive time Millisecond
spring.adatasource.timeBetweenEvictionRunsMillis=60000
# the minalive time outMillisecond
spring.adatasource.minEvictableIdleTimeMillis=300000
spring.adatasource.validationQuery=SELECT 1 FROM DUAL
spring.adatasource.testWhileIdle=true
spring.adatasource.testOnBorrow=false
spring.adatasource.testOnReturn=false
# pool pscache size
spring.adatasource.poolPreparedStatements=true
spring.adatasource.maxPoolPreparedStatementPerConnectionSize=20
## 配置了之后druid监控sql,才会有数据
spring.adatasource.filters=stat,wall,logback
## 配置查询慢的sql,慢的标准
spring.adatasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#--------------------------------------------------------------------------------------------------------
spring.orc.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.orc.datasource.url=jdbc:oracle:thin:@192.168.22.235:1521:nettest
spring.orc.datasource.username=wxapp1
spring.orc.datasource.password=wxapp1
# init pool size
spring.orc.datasource.initialSize=5
spring.orc.datasource.minIdle=5
spring.orc.datasource.maxActive=20
# wait time out Millisecond
spring.orc.datasource.maxWait=60000
# check alive time Millisecond
spring.orc.datasource.timeBetweenEvictionRunsMillis=60000
# the minalive time outMillisecond
spring.orc.datasource.minEvictableIdleTimeMillis=300000
spring.orc.datasource.validationQuery=SELECT 1 FROM DUAL
spring.orc.datasource.testWhileIdle=true
spring.orc.datasource.testOnBorrow=false
spring.orc.datasource.testOnReturn=false
# pool pscache size
spring.orc.datasource.poolPreparedStatements=true
spring.orc.datasource.maxPoolPreparedStatementPerConnectionSize=20
## 配置了之后druid监控sql,才会有数据
spring.orc.datasource.filters=stat,wall,logback
## 配置查询慢的sql,慢的标准
spring.orc.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#-----------------------------------------------------------------------------------------------------
代码结构如下
不同数据库的业务,使用不同的文件夹区分开来,然后再数据库映射文件的时候,指定扫描不同的包
这样就可以实现多数据源接入了。
这种配置不能实现 多数据源分布式事物。。
多数据源分布式使用需要使用插件支持,Atomikos
支持分布式事物的配置方法
mysql 1,druid 配置文件
package com.config;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
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 org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.cat.common.mybatis.SqlSessionFactoryBean;
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages= {"com.smk.push.**.dao","com.cat.**.dao"},sqlSessionTemplateRef="userSqlSessionTemplate")
public class DruidConfig {
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
reg.addInitParameter("loginUsername", "luoyang");
reg.addInitParameter("loginPassword", "luoyang123456");
reg.addInitParameter("allow", "*");
reg.addInitParameter("resetEnable", "false");
return reg;
}
@Bean(name="filterRegistrationBean")
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
filterRegistrationBean.addInitParameter("profileEnable", "true");
filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
filterRegistrationBean.setFilter(new WebStatFilter());
return filterRegistrationBean;
}
/* // 按照BeanId来拦截配置 用来bean的监控
@Bean(value = "druid-stat-interceptor")
public DruidStatInterceptor druidStatInterceptor() {
DruidStatInterceptor druidStatInterceptor = new DruidStatInterceptor();
return druidStatInterceptor;
} */
@Bean(name="dataSource")
@Primary
public DataSource druidDataSource(){
DruidXADataSource dataSource=new DruidXADataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://192.168.23.212:3306/smk_push?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true");
dataSource.setUsername("root");
dataSource.setPassword("123456");
//配置最大连接
dataSource.setMaxActive(300);
//配置初始连接
dataSource.setInitialSize(20);
//配置最小连接
dataSource.setMinIdle(10);
//连接等待超时时间
dataSource.setMaxWait(60000);
//间隔多久进行检测,关闭空闲连接
dataSource.setTimeBetweenEvictionRunsMillis(60000);
//一个连接最小生存时间
dataSource.setMinEvictableIdleTimeMillis(300000);
//连接等待超时时间 单位为毫秒 缺省启用公平锁,
//并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁
dataSource.setUseUnfairLock(true);
//用来检测是否有效的sql
dataSource.setValidationQuery("SELECT 1 FROM DUAL");
dataSource.setTestWhileIdle(true);
//申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能
dataSource.setTestOnBorrow(false);
//归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能
dataSource.setTestOnReturn(false);
//打开PSCache,并指定每个连接的PSCache大小启用poolPreparedStatements后,
//PreparedStatements 和CallableStatements 都会被缓存起来复用,
//即相同逻辑的SQL可以复用一个游标,这样可以减少创建游标的数量。
dataSource.setPoolPreparedStatements(true);
dataSource.setMaxOpenPreparedStatements(20);
try {
//配置sql监控的filter
dataSource.setFilters("stat,wall,log4j");
dataSource.init();
} catch (Exception e) {
e.printStackTrace();
}
AtomikosDataSourceBean atomikosDataSourceBean=new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSource(dataSource);
atomikosDataSourceBean.setUniqueResourceName("test1Datasource");
return atomikosDataSourceBean;
}
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
System.out.println("sqlSessionFactory init ");
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:msq/**/*.xml"));
/*sqlSessionFactoryBean.setPlugins(new Interceptor[]{new AparamsInterceptor(),new ResultInterceptor(),
new ParameterInterceptor(),new StatementInterceptor()});*/
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory);
return template;
}
/**
* 配置事务管理器
*/
@Bean(name="smkAppTransaction")
public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
mysql 2 druid 数据源配置
package com.config;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.cat.common.mybatis.SqlSessionFactoryBean;
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = { "com.smk.weixin.**.dao" }, sqlSessionTemplateRef = "abcSqlSessionTemplate")
public class MysqWeiDruidConfig {
@Bean(name = "orcDataSource")
public DataSource druidDataSource() {
DruidXADataSource dataSource = new DruidXADataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource
.setUrl("jdbc:mysql://192.168.23.212:3306/smk_weixin?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// 配置最大连接
dataSource.setMaxActive(300);
// 配置初始连接
dataSource.setInitialSize(20);
// 配置最小连接
dataSource.setMinIdle(10);
// 连接等待超时时间
dataSource.setMaxWait(60000);
// 间隔多久进行检测,关闭空闲连接
dataSource.setTimeBetweenEvictionRunsMillis(60000);
// 一个连接最小生存时间
dataSource.setMinEvictableIdleTimeMillis(300000);
// 连接等待超时时间 单位为毫秒 缺省启用公平锁,
// 并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁
dataSource.setUseUnfairLock(true);
// 用来检测是否有效的sql
dataSource.setValidationQuery("SELECT 1 FROM DUAL");
dataSource.setTestWhileIdle(true);
// 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能
dataSource.setTestOnBorrow(false);
// 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能
dataSource.setTestOnReturn(false);
// 打开PSCache,并指定每个连接的PSCache大小启用poolPreparedStatements后,
// PreparedStatements 和CallableStatements 都会被缓存起来复用,
// 即相同逻辑的SQL可以复用一个游标,这样可以减少创建游标的数量。
dataSource.setPoolPreparedStatements(true);
dataSource.setMaxOpenPreparedStatements(20);
try {
//配置sql监控的filter
dataSource.setFilters("stat,wall,log4j");
dataSource.init();
} catch (SQLException e) {
e.printStackTrace();
}
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSource(dataSource);
atomikosDataSourceBean.setUniqueResourceName("test2Datasource");
return atomikosDataSourceBean;
}
@Bean(name = "orcSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("orcDataSource") DataSource dataSource) throws Exception {
System.out.println("sqlSessionFactory init ");
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:msqw/**/*.xml"));
/*
* sqlSessionFactoryBean.setPlugins(new Interceptor[]{new
* AparamsInterceptor(),new ResultInt erceptor(), new
* ParameterInterceptor(),new StatementInterceptor()});
*/
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate abcSqlSessionTemplate(
@Qualifier("orcSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory);
return template;
}
/**
* 配置事务管理器
*/
@Bean(name = "orcTransaction")
public PlatformTransactionManager transactionManager(@Qualifier("orcDataSource") DataSource dataSource)
throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
分布式事务管理器配置
package com.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.jta.JtaTransactionManager;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
@Configuration
@EnableTransactionManagement
@ComponentScan
public class JtaTranConfig {
/**
* 配置事务管理器
*/
@Bean(name="jtaTransaction")
@Primary
public JtaTransactionManager jtaTransactionManager() throws Exception {
UserTransactionImp uti = new UserTransactionImp();
UserTransactionManager um = new UserTransactionManager();
um.setForceShutdown(true);
return new JtaTransactionManager(uti, um);
}
}
基于以上的配置,就可以实现2个mysql 的 分布式事物
在这里说明一点,使用oracle数据库,实现分布式事物,我这里一直没有实现成功
报错信息:
2018-11-29 18:27:41.137 [http-nio-8080-exec-3] WARN com.atomikos.datasource.xa.XAResourceTransaction - XA resource 'test2Datasource': resume for XID '31302E3130312E372E3136382E746D30303030313030303031:31302E3130312E372E3136382E746D31' raised -3: the XA resource detected an internal error
oracle.jdbc.xa.OracleXAException: null
at oracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:1135)
at oracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:233)
at com.atomikos.datasource.xa.XAResourceTransaction.resume(XAResourceTransaction.java:427)
at com.atomikos.datasource.xa.session.BranchEnlistedStateHandler.<init>(BranchEnlistedStateHandler.java:59)
at com.atomikos.datasource.xa.session.NotInBranchStateHandler.checkEnlistBeforeUse(NotInBranchStateHandler.java:64)
at com.atomikos.datasource.xa.session.TransactionContext.checkEnlistBeforeUse(TransactionContext.java:88)
at com.atomikos.datasource.xa.session.SessionHandleState.notifyBeforeUse(SessionHandleState.java:179)
at com.atomikos.jdbc.AtomikosConnectionProxy.enlist(AtomikosConnectionProxy.java:223)
at com.atomikos.jdbc.AtomikosConnectionProxy.invoke(AtomikosConnectionProxy.java:142)
at com.sun.proxy.$Proxy93.prepareStatement(Unknown Source)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87)
at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
at org.apache.ibatis.executor.keygen.SelectKeyGenerator.processGeneratedKeys(SelectKeyGenerator.java:68)
at org.apache.ibatis.executor.keygen.SelectKeyGenerator.processBefore(SelectKeyGenerator.java:47)
at org.apache.ibatis.executor.statement.BaseStatementHandler.generateKeys(BaseStatementHandler.java:141)
at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:63)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:40)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:46)
at com.cat.common.mybatis.Configuration.newStatementHandler(Configuration.java:470)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
at com.sun.proxy.$Proxy76.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
at com.cat.common.mybatis.MapperMethod.execute(MapperMethod.java:47)
at com.cat.common.mybatis.MapperProxy.invoke(MapperProxy.java:38)
at com.sun.proxy.$Proxy77.save(Unknown Source)
at com.smk.orc.service.NewsSmkAdviseService.save(NewsSmkAdviseService.java:40)
at com.smk.orc.service.NewsSmkAdviseService.moreTra(NewsSmkAdviseService.java:118)
at com.smk.orc.service.NewsSmkAdviseService$$FastClassBySpringCGLIB$$ec174120.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.smk.orc.service.NewsSmkAdviseService$$EnhancerBySpringCGLIB$$ae4da3bc.moreTra(<generated>)
at com.smk.orc.action.NewsSmkAction.testTra(NewsSmkAction.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)
at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.ha.session.JvmRouteBinderValve.invoke(JvmRouteBinderValve.java:218)
at org.apache.catalina.ha.tcp.ReplicationValve.invoke(ReplicationValve.java:333)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1700)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.sql.SQLException: ORA-06550: 第 1 行, 第 14 列:
PLS-00201: identifier 'JAVA_XA.XA_START_NEW' must be declared
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:205)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1043)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1336)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3613)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3714)
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4755)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1378)
at oracle.jdbc.xa.client.OracleXAResource.doStart(OracleXAResource.java:279)
at oracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:228)
... 118 common frames omitted
2018-11-29 18:27:41.148 [http-nio-8080-exec-3] WARN com.atomikos.jdbc.JdbcConnectionProxyHelper - Error enlisting in transaction - connection might be broken? Please check the logs for more information...
com.atomikos.datasource.ResourceException: XA resource 'test2Datasource': resume for XID '31302E3130312E372E3136382E746D30303030313030303031:31302E3130312E372E3136382E746D31' raised -3: the XA resource detected an internal error
at com.atomikos.datasource.xa.XAResourceTransaction.resume(XAResourceTransaction.java:434)
at com.atomikos.datasource.xa.session.BranchEnlistedStateHandler.<init>(BranchEnlistedStateHandler.java:59)
at com.atomikos.datasource.xa.session.NotInBranchStateHandler.checkEnlistBeforeUse(NotInBranchStateHandler.java:64)
at com.atomikos.datasource.xa.session.TransactionContext.checkEnlistBeforeUse(TransactionContext.java:88)
at com.atomikos.datasource.xa.session.SessionHandleState.notifyBeforeUse(SessionHandleState.java:179)
at com.atomikos.jdbc.AtomikosConnectionProxy.enlist(AtomikosConnectionProxy.java:223)
at com.atomikos.jdbc.AtomikosConnectionProxy.invoke(AtomikosConnectionProxy.java:142)
at com.sun.proxy.$Proxy93.prepareStatement(Unknown Source)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87)
at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
at org.apache.ibatis.executor.keygen.SelectKeyGenerator.processGeneratedKeys(SelectKeyGenerator.java:68)
at org.apache.ibatis.executor.keygen.SelectKeyGenerator.processBefore(SelectKeyGenerator.java:47)
at org.apache.ibatis.executor.statement.BaseStatementHandler.generateKeys(BaseStatementHandler.java:141)
at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:63)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:40)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:46)
at com.cat.common.mybatis.Configuration.newStatementHandler(Configuration.java:470)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
at com.sun.proxy.$Proxy76.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
at com.cat.common.mybatis.MapperMethod.execute(MapperMethod.java:47)
at com.cat.common.mybatis.MapperProxy.invoke(MapperProxy.java:38)
at com.sun.proxy.$Proxy77.save(Unknown Source)
at com.smk.orc.service.NewsSmkAdviseService.save(NewsSmkAdviseService.java:40)
at com.smk.orc.service.NewsSmkAdviseService.moreTra(NewsSmkAdviseService.java:118)
at com.smk.orc.service.NewsSmkAdviseService$$FastClassBySpringCGLIB$$ec174120.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.smk.orc.service.NewsSmkAdviseService$$EnhancerBySpringCGLIB$$ae4da3bc.moreTra(<generated>)
at com.smk.orc.action.NewsSmkAction.testTra(NewsSmkAction.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(Http
看其他人的帖子说需要使用管理员账号对于当前用户分配一下权限:
grant select on sys.dba_pending_transactions to <user_name>;
grant select on sys.pending_trans$ to <user_name>;
grant select on sys.dba_2pc_pending to <user_name>;
grant execute on sys.dbms_system to <user_name>;
试过了之后,还是不行。。。
然后就放着没有继续研究oracle 的分布式事物了,有成功过的,还请教一下我,不胜感激。