我有一个使用Atomikos进行JTA托管交易的Spring Boot应用程序。它使用多个DataSource来连接多个数据库。
第一个请求会返回预期的结果,但第二个请求会因“游戏池耗尽”而失效。异常。
我用普通的JDBC和JdbcTemplate尝试了它,没有结果。它是一样的。
这是我的Spring Boot Version 1.5.8.RELEASE
的代码@SpringBootApplication
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class, //if you are using Hibernate
DataSourceTransactionManagerAutoConfiguration.class
})
@EnableTransactionManagement
public class App {
public static void main(String[] arg) {
SpringApplication.run(App.class, arg);
}
}
第一种方法' index()'是用简单的JDBC。第二个' a()'与JdbcTemplate一起使用。
@RestController
@RequestMapping(value = "/demo")
@RequestScoped
public class Controller {
@Autowired
ApplicationContext ctx;
@RequestMapping("")
@org.springframework.transaction.annotation.Transactional(propagation = Propagation.REQUIRES_NEW)
public String index() throws SQLException {
DataSource imsdb = ctx.getBean("IMSDB", DataSource.class);
Connection icon = imsdb.getConnection();
DataSource sqldb = ctx.getBean("SQLDB", DataSource.class);
Connection con = sqldb.getConnection();
con.setAutoCommit(false);
PreparedStatement stmt = con.prepareStatement("select current date from sysibm.sysdummy1");
ParameterMetaData md = stmt.getParameterMetaData();
md.getParameterCount();
ResultSet rs = stmt.executeQuery();
ResultSetMetaData rmd = rs.getMetaData();
rmd.getColumnName(1);
rs.next();
Date date = rs.getDate(1);
rs.close();
stmt.close();
PreparedStatement istmt = icon.prepareStatement("select current date from sysibm.sysdummy1");
ParameterMetaData imd = istmt.getParameterMetaData();
imd.getParameterCount();
ResultSet irs = istmt.executeQuery();
ResultSetMetaData irmd = irs.getMetaData();
irmd.getColumnName(1);
irs.next();
Date idate = irs.getDate(1);
irs.close();
istmt.close();
con.close();
icon.close();
return "dd";
}
@RequestMapping("/a")
@org.springframework.transaction.annotation.Transactional(transactionManager = "transactionManager")
public String a() throws SQLException {
DataSource imsdb = ctx.getBean("IMSDB", DataSource.class);
JdbcTemplate t1 = new JdbcTemplate(imsdb);
DataSource sqldb = ctx.getBean("SQLDB", DataSource.class);
JdbcTemplate t2 = new JdbcTemplate(sqldb);
SqlRowSet rs = t1.queryForRowSet("select current date from sysibm.sysdummy1");
rs.next();
Date date = rs.getDate(1);
SqlRowSet rs2 = t2.queryForRowSet("select current date from sysibm.sysdummy1");
rs2.next();
Date date2 = rs2.getDate(1);
return date.toLocalDate().format(DateTimeFormatter.ISO_DATE);
}
}
DataSource配置:
@Configuration
@DependsOn("transactionManager")
public class DatabaseSqlConfig {
@Primary
@Bean(name = "SQLDB")
@ConfigurationProperties(prefix = "spring.jta.atomikos.datasource.sql")
public DataSource SQLDB() {
return new AtomikosDataSourceBean();
}
@Bean(name = "IMSDB")
@ConfigurationProperties(prefix = "spring.jta.atomikos.datasource.ims")
public DataSource IMSDB() {
return new AtomikosDataSourceBean();
}
}
交易经理:
@Configuration
@ComponentScan
@EnableTransactionManagement
public class MainConfig {
@Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(120);
return userTransactionImp;
}
@Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
public TransactionManager atomikosTransactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
userTransactionManager.setTransactionTimeout(120);
return userTransactionManager;
}
@Bean(name = "transactionManager")
@DependsOn({ "userTransaction", "atomikosTransactionManager" })
public JtaTransactionManager transactionManager() throws Throwable {
UserTransaction userTransaction = userTransaction();
TransactionManager atomikosTransactionManager = atomikosTransactionManager();
return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
}
}
应用程序yml:
spring:
jta:
atomikos:
datasource:
sql:
unique-resource-name: sql
xa-data-source-class-name: com.ibm.db2.jcc.DB2XADataSource
xa-properties:
serverName: 10.141.86.14
portNumber: 50000
databaseName: XXX
user: XXX
password: db2
driverType: 4
initQuery: set current sqlid = 'LVM'
testOnBorrow: true
validationQuery: select 1 from sysibm.sysdummy1
defaultAutoCommit: false
max-pool-size: 1
min-pool-size: 1
reap-timeout: 10
ims:
unique-resource-name: ims
xa-data-source-class-name: com.ibm.db2.jcc.DB2XADataSource
xa-properties:
serverName: 10.141.86.14
portNumber: 50000
databaseName: XXX
user: XXX
password: XXX
driverType: 4
initQuery: set current sqlid = 'XXX'
testOnBorrow: true
validationQuery: select 1 from sysibm.sysdummy1
defaultAutoCommit: false
max-pool-size: 1
min-pool-size: 1
reap-timeout: 10
和pom deps:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>db2jcc4</artifactId>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
这是日志:
第一次请求:
atomikos connection proxy for com.ibm.db2.jcc.am.sf@8ecb39e: calling createStatement...
2017-11-07 10:36:09.930 DEBUG 14473 --- [nio-8080-exec-1] c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'sql': getConnection()...
2017-11-07 10:36:09.930 INFO 14473 --- [nio-8080-exec-1] c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'sql': init...
2017-11-07 10:36:09.931 DEBUG 14473 --- [nio-8080-exec-1] c.a.icatch.imp.CompositeTransactionImp : addParticipant ( XAResourceTransaction: 3132372E302E312E312E746D313531303034373336393836313030303031:3132372E302E312E312E746D32 ) for transaction 127.0.1.1.tm151004736986100001
2017-11-07 10:36:09.931 DEBUG 14473 --- [nio-8080-exec-1] c.a.datasource.xa.XAResourceTransaction : XAResource.start ( 3132372E302E312E312E746D313531303034373336393836313030303031:3132372E302E312E312E746D32 , XAResource.TMNOFLAGS ) on resource sql represented by XAResource instance com.ibm.db2.jcc.t4.ec@7286dbb3
2017-11-07 10:36:09.931 DEBUG 14473 --- [nio-8080-exec-1] c.a.icatch.imp.CompositeTransactionImp : registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@a9b32dad ) for transaction 127.0.1.1.tm151004736986100001
2017-11-07 10:36:09.931 DEBUG 14473 --- [nio-8080-exec-1] c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.ibm.db2.jcc.am.sf@5e7e3715: calling createStatement...
2017-11-07 10:36:09.934 DEBUG 14473 --- [nio-8080-exec-1] c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.ibm.db2.jcc.am.sf@8ecb39e: close()...
2017-11-07 10:36:09.935 DEBUG 14473 --- [nio-8080-exec-1] c.a.datasource.xa.XAResourceTransaction : XAResource.end ( 3132372E302E312E312E746D313531303034373336393836313030303031:3132372E302E312E312E746D31 , XAResource.TMSUCCESS ) on resource ims represented by XAResource instance com.ibm.db2.jcc.t4.ec@44c74226
2017-11-07 10:36:09.935 DEBUG 14473 --- [nio-8080-exec-1] c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.ibm.db2.jcc.am.sf@5e7e3715: close()...
2017-11-07 10:36:09.935 DEBUG 14473 --- [nio-8080-exec-1] c.a.datasource.xa.XAResourceTransaction : XAResource.end ( 3132372E302E312E312E746D313531303034373336393836313030303031:3132372E302E312E312E746D32 , XAResource.TMSUCCESS ) on resource sql represented by XAResource instance com.ibm.db2.jcc.t4.ec@7286dbb3
2017-11-07 10:36:09.936 DEBUG 14473 --- [nio-8080-exec-1] c.a.icatch.imp.CompositeTransactionImp : commit() done (by application) of transaction 127.0.1.1.tm151004736986100001
2017-11-07 10:36:09.938 DEBUG 14473 --- [nio-8080-exec-1] c.a.datasource.xa.XAResourceTransaction : XAResource.prepare ( 3132372E302E312E312E746D313531303034373336393836313030303031:3132372E302E312E312E746D31 ) returning XAResource.XA_RDONLY on resource ims represented by XAResource instance com.ibm.db2.jcc.t4.ec@44c74226
2017-11-07 10:36:09.938 DEBUG 14473 --- [nio-8080-exec-1] c.a.datasource.xa.XAResourceTransaction : XAResource.prepare ( 3132372E302E312E312E746D313531303034373336393836313030303031:3132372E302E312E312E746D32 ) returning XAResource.XA_RDONLY on resource sql represented by XAResource instance com.ibm.db2.jcc.t4.ec@7286dbb3
第二次请求,直到例外:
2017-11-07 10:36:12.635 DEBUG 14473 --- [nio-8080-exec-2] c.a.i.i.CompositeTransactionManagerImp : createCompositeTransaction ( 10000 ): created new ROOT transaction with id 127.0.1.1.tm151004737263500002
2017-11-07 10:36:12.635 DEBUG 14473 --- [nio-8080-exec-2] c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'ims': getConnection()...
2017-11-07 10:36:12.635 INFO 14473 --- [nio-8080-exec-2] c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'ims': init...
2017-11-07 10:36:22.693 WARN 14473 --- [ Atomikos:4] c.a.icatch.imp.ActiveStateHandler : Timeout/setRollbackOnly of ACTIVE coordinator !
2017-11-07 10:36:42.637 WARN 14473 --- [nio-8080-exec-2] com.atomikos.jdbc.AtomikosSQLException : Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.
2017-11-07 10:36:42.639 DEBUG 14473 --- [nio-8080-exec-2] c.a.icatch.imp.CompositeTransactionImp : rollback() done of transaction 127.0.1.1.tm151004737263500002
2017-11-07 10:36:42.640 DEBUG 14473 --- [nio-8080-exec-2] c.a.icatch.imp.CompositeTransactionImp : rollback() done of transaction 127.0.1.1.tm151004737263500002
2017-11-07 10:36:42.649 ERROR 14473 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.atomikos.jdbc.AtomikosSQLException: Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.] with root cause
com.atomikos.jdbc.AtomikosSQLException: Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.
答案 0 :(得分:0)
我自己找到了解决方案。
Atomikos事务管理器只是有一个错误 - 我切换到Bitronix,现在一切正常。
答案 1 :(得分:0)
这是4.0.4中的已知问题 - 将在TransactionsEssentials的4.0.5中修复。