java事务的作用范围,java – 在一个全局事务的范围内使用JTA同时向不同的数据源调用几个查询...

我有一个带有3个分布式dataSources的应用程序(com.atomikos.jdbc.AtomikosDataSourceBean).我正在使用Atomikos事务管理器作为JTA实现.每个dataSource都与 PostgreSQL 数据库一起使用.

现在,我正在调用我对每个dataSource的查询,一切正常.

我想知道,如果有可能,使用JTA,并行调用我的查询(多线程,并发)?

我尝试使用jdbcTemplate(Spring)简单地在新创建的线程中调用查询.首先,我遇到了一个春天问题. Spring将事务上下文存储在ThreadLocal字段中,因此在我的新线程( Spring transaction manager and multithreading

)中无法正确解析.我已经通过将相同的事务上下文设置为新创建的线程的ThreadLocal来解决了这个问题.

但是我在Atomikos代码中面临同样的问题.它们还将CompositeTransactionImp存储在线程范围映射(BaseTrancationManager#getCurrentTx)中.但在Atomikos案例中,不可能为新线程设置值.

所以我不能同时执行我的查询,因为似乎Atomikos不支持这种方法.

但我也查看了JTA规范并发现了以下内容:“多个线程可能同时与同一个全局事务关联.” (“3.2 TransactionManager Interface”, http://download.oracle.com/otndocs/jcp/jta-1.1-spec-oth-JSpec/?submit=Download

)

问题:如何在一个全局事务的范围内使用JTA(2阶段提交)同时向不同的dataSource调用两个或多个查询?

在tomcat上下文中配置DataSources:

factory="com.company.package.AtomikosDataSourceBeanFactory"

xaDataSourceClassName="org.postgresql.xa.PGXADataSource"

xaProperties.serverName="localhost"

xaProperties.portNumber="5451"

xaProperties.databaseName="db1"

uniqueResourceName="jdbc/db1"

xaProperties.user="secretpassword"

xaProperties.password="secretpassword"

minPoolSize="5"

maxPoolSize="10"

testQuery="SELECT 1" />

factory="com.company.package.AtomikosDataSourceBeanFactory"

xaDataSourceClassName="org.postgresql.xa.PGXADataSource"

xaProperties.serverName="localhost"

xaProperties.portNumber="5451"

xaProperties.databaseName="db2"

uniqueResourceName="jdbc/db2"

xaProperties.user="secretpassword"

xaProperties.password="secretpassword"

minPoolSize="5"

maxPoolSize="10"

testQuery="SELECT 1" />

factory="com.company.package.AtomikosDataSourceBeanFactory"

xaDataSourceClassName="org.postgresql.xa.PGXADataSource"

xaProperties.serverName="localhost"

xaProperties.portNumber="5451"

xaProperties.databaseName="db3"

uniqueResourceName="jdbc/db3"

xaProperties.user="secretpassword"

xaProperties.password="secretpassword"

minPoolSize="5"

maxPoolSize="10"

testQuery="SELECT 1" />

Spring环境中的事务管理器配置:

init-method="init" destroy-method="close" lazy-init="true">

码:

final SqlParameterSource parameters = getSqlParameterSourceCreator().convert(entity);

// Solving Spring's ThreadLocal issue: saving thread local params

final Map resourceMap = TransactionSynchronizationManager.getResourceMap();

final List synchronizations = TransactionSynchronizationManager.getSynchronizations();

final boolean actualTransactionActive = TransactionSynchronizationManager.isActualTransactionActive();

final String currentTransactionName = TransactionSynchronizationManager.getCurrentTransactionName();

final AtomicReference exceptionHolder = new AtomicReference();

// Running query in a separate thread.

final Thread thread = new Thread(new Runnable() {

@Override

public void run() {

try {

// Solving Spring's ThreadLocal issue: setting thread local values to newly created thread.

for (Map.Entry entry : resourceMap.entrySet()) {

TransactionSynchronizationManager.bindResource(entry.getKey(), entry.getValue());

}

if (synchronizations != null && !synchronizations.isEmpty()) {

TransactionSynchronizationManager.initSynchronization();

for (TransactionSynchronization synchronization : synchronizations) {

TransactionSynchronizationManager.registerSynchronization(synchronization);

}

}

TransactionSynchronizationManager.setActualTransactionActive(actualTransactionActive);

TransactionSynchronizationManager.setCurrentTransactionName(currentTransactionName);

// Executing query.

final String query = "insert into ...";

NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSourceOne);

template.update(query, parameters);

} catch (final Throwable ex) {

exceptionHolder.set(ex);

}

}

});

thread.start();

// ... same code as above for other dataSources.

// allThreds.join(); - joining to all threads.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值