Spring 引导路由数据源无法正常工作
Spring boot routing datasource not work correctly
我正在使用 Postgres、Hibernate、Atomikos、JPA 和 Thymeleaf 配置 spring 引导 Web 应用程序。
我使用 AbstractRoutingDataSource 路由到新数据源,如下所示:
@Override
protected Object determineCurrentLookupKey() {
String currentTenantId = TenantContextHolder.getCurrentTenantId();
// Get endpoint, database name from default database
// New datasource
DataSource dataSource = constructDataSource(setting, endpoint, databaseName);
resolvedDataSourceMap.putIfAbsent(currentTenantId, dataSource);
setTargetDataSources(resolvedDataSourceMap);
afterPropertiesSet();
return currentTenantId;
}
如果我打电话给
userRepository.countByUserId("aaa"); // This is custom method in my repository
,它路由并且 return 结果正确,但如果我调用
userRepository.findAll(); // My repository extends from SimpleJPARepository
,我总是得到以下错误(如果我再次调用,它会工作正常!)
请帮助我解释为什么以及我应该如何解决这个错误。
2018-03-24 12:03:47.566 INFO 17472 --- [nio-8080-exec-2] c.a.d.xa.XATransactionalResource : 0000000002-pgxad: refreshed XAResource
2018-03-24 12:03:47.702 ERROR 17472 --- [nio-8080-exec-2] c.a.datasource.xa.XAResourceTransaction : XA resource 'defaultDataSource-pgxad': prepare for XID '3139322E3136382E31372E3135352E746D313532313836373830313734343030303032:3139322E3136382E31372E3135352E746D32' raised -3: the XA resource detected an internal error
org.postgresql.xa.PGXAException: Error preparing transaction
at org.postgresql.xa.PGXAConnection.prepare(PGXAConnection.java:309) ~[postgresql-42.2.1.jar:42.2.1]
at com.atomikos.datasource.xa.XAResourceTransaction.prepare(XAResourceTransaction.java:384) ~[transactions-jta-4.0.6.jar:na]
at com.atomikos.icatch.imp.PrepareMessage.send(PrepareMessage.java:40) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.PrepareMessage.send(PrepareMessage.java:19) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.PropagationMessage.submit(PropagationMessage.java:67) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.Propagator$PropagatorThread.run(Propagator.java:63) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.Propagator.submitPropagationMessage(Propagator.java:42) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.ActiveStateHandler.prepare(ActiveStateHandler.java:171) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.prepare(CoordinatorImp.java:523) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.terminate(CoordinatorImp.java:687) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.CompositeTransactionImp.commit(CompositeTransactionImp.java:282) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:172) [transactions-jta-4.0.6.jar:na]
at com.atomikos.icatch.jta.TransactionManagerImp.commit(TransactionManagerImp.java:414) [transactions-jta-4.0.6.jar:na]
at com.atomikos.icatch.jta.UserTransactionImp.commit(UserTransactionImp.java:86) [transactions-jta-4.0.6.jar:na]
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1040) [spring-tx-5.0.4.RELEASE.jar:5.0.4.RELEASE]
...
Caused by: org.postgresql.util.PSQLException: ERROR: 準備されたトランザクションは無効です。
Hint: max_prepared_transactionsを非ゼロに設定してください。
...
2018-03-24 12:03:47.715 ERROR 17472 --- [nio-8080-exec-2] c.a.datasource.xa.XAResourceTransaction : XA resource '0000000002-pgxad': prepare for XID '3139322E3136382E31372E3135352E746D313532313836373830313734343030303032:3139322E3136382E31372E3135352E746D33' raised -3: the XA resource detected an internal error
org.postgresql.xa.PGXAException: Error preparing transaction
at org.postgresql.xa.PGXAConnection.prepare(PGXAConnection.java:309) ~[postgresql-42.2.1.jar:42.2.1]
at com.atomikos.datasource.xa.XAResourceTransaction.prepare(XAResourceTransaction.java:384) ~[transactions-jta-4.0.6.jar:na]
在同一个事务中访问2个数据库时出错。
因此,我需要通过 REQUIRE_NEW 创建新交易,如下所示:
@Transactional(propagation = Propagation.REQUIRES_NEW)
Tenant findByTenantId(Long tenantId);
或者,如@a_horse_with_no_name所说,"need to set max_prepared_transactions to something greater than the default of 0 in order to use 2phase commits and distributed transactions"。
感谢您的回复,@a_horse_with_no_name!
我正在使用 Postgres、Hibernate、Atomikos、JPA 和 Thymeleaf 配置 spring 引导 Web 应用程序。 我使用 AbstractRoutingDataSource 路由到新数据源,如下所示:
@Override
protected Object determineCurrentLookupKey() {
String currentTenantId = TenantContextHolder.getCurrentTenantId();
// Get endpoint, database name from default database
// New datasource
DataSource dataSource = constructDataSource(setting, endpoint, databaseName);
resolvedDataSourceMap.putIfAbsent(currentTenantId, dataSource);
setTargetDataSources(resolvedDataSourceMap);
afterPropertiesSet();
return currentTenantId;
}
如果我打电话给
userRepository.countByUserId("aaa"); // This is custom method in my repository
,它路由并且 return 结果正确,但如果我调用
userRepository.findAll(); // My repository extends from SimpleJPARepository
,我总是得到以下错误(如果我再次调用,它会工作正常!) 请帮助我解释为什么以及我应该如何解决这个错误。
2018-03-24 12:03:47.566 INFO 17472 --- [nio-8080-exec-2] c.a.d.xa.XATransactionalResource : 0000000002-pgxad: refreshed XAResource
2018-03-24 12:03:47.702 ERROR 17472 --- [nio-8080-exec-2] c.a.datasource.xa.XAResourceTransaction : XA resource 'defaultDataSource-pgxad': prepare for XID '3139322E3136382E31372E3135352E746D313532313836373830313734343030303032:3139322E3136382E31372E3135352E746D32' raised -3: the XA resource detected an internal error
org.postgresql.xa.PGXAException: Error preparing transaction
at org.postgresql.xa.PGXAConnection.prepare(PGXAConnection.java:309) ~[postgresql-42.2.1.jar:42.2.1]
at com.atomikos.datasource.xa.XAResourceTransaction.prepare(XAResourceTransaction.java:384) ~[transactions-jta-4.0.6.jar:na]
at com.atomikos.icatch.imp.PrepareMessage.send(PrepareMessage.java:40) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.PrepareMessage.send(PrepareMessage.java:19) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.PropagationMessage.submit(PropagationMessage.java:67) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.Propagator$PropagatorThread.run(Propagator.java:63) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.Propagator.submitPropagationMessage(Propagator.java:42) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.ActiveStateHandler.prepare(ActiveStateHandler.java:171) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.prepare(CoordinatorImp.java:523) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.terminate(CoordinatorImp.java:687) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.imp.CompositeTransactionImp.commit(CompositeTransactionImp.java:282) [transactions-4.0.6.jar:na]
at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:172) [transactions-jta-4.0.6.jar:na]
at com.atomikos.icatch.jta.TransactionManagerImp.commit(TransactionManagerImp.java:414) [transactions-jta-4.0.6.jar:na]
at com.atomikos.icatch.jta.UserTransactionImp.commit(UserTransactionImp.java:86) [transactions-jta-4.0.6.jar:na]
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1040) [spring-tx-5.0.4.RELEASE.jar:5.0.4.RELEASE]
...
Caused by: org.postgresql.util.PSQLException: ERROR: 準備されたトランザクションは無効です。
Hint: max_prepared_transactionsを非ゼロに設定してください。
...
2018-03-24 12:03:47.715 ERROR 17472 --- [nio-8080-exec-2] c.a.datasource.xa.XAResourceTransaction : XA resource '0000000002-pgxad': prepare for XID '3139322E3136382E31372E3135352E746D313532313836373830313734343030303032:3139322E3136382E31372E3135352E746D33' raised -3: the XA resource detected an internal error
org.postgresql.xa.PGXAException: Error preparing transaction
at org.postgresql.xa.PGXAConnection.prepare(PGXAConnection.java:309) ~[postgresql-42.2.1.jar:42.2.1]
at com.atomikos.datasource.xa.XAResourceTransaction.prepare(XAResourceTransaction.java:384) ~[transactions-jta-4.0.6.jar:na]
在同一个事务中访问2个数据库时出错。 因此,我需要通过 REQUIRE_NEW 创建新交易,如下所示:
@Transactional(propagation = Propagation.REQUIRES_NEW)
Tenant findByTenantId(Long tenantId);
或者,如@a_horse_with_no_name所说,"need to set max_prepared_transactions to something greater than the default of 0 in order to use 2phase commits and distributed transactions"。
感谢您的回复,@a_horse_with_no_name!