我们使用 Spring 和 Hibernate 来与 JTA 建立事务。 PlatformTransactionManager 是 JtaTransactionManager,它与 narayana 的 TransactionManager 和 UserTransaction 连接。
@Bean
@Scope("prototype")
public TransactionManager jbossTransactionManager() {
return jtaPropertyManager.getJTAEnvironmentBean().getTransactionManager();
}
@Bean
@Scope("prototype")
public UserTransaction jbossUserTransaction() {
return jtaPropertyManager.getJTAEnvironmentBean().getUserTransaction();
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JtaTransactionManager(jbossUserTransaction(), jbossTransactionManager());
}
我注意到 JtaTransactionManager 有我想要的 UT 和 TM。在 JBoss 6 EAP 上,我注意到我的 DataSource 已被用作 WrapperDataSource,并且这与不同的 TM 相关。具体来说,它使用 TransactionManagerDelegate。这似乎是 JBoss 通过 JNDI 名称 java:TransactionManager 和 java:jboss/TransactionManager 提供的事务管理器。这阻止了我的事务具有事务边界,并且我在刷新时泄漏数据。如果我从容器中删除我的配置以及 UT 和 TM,我的交易将正常进行。
- 是什么决定使用另一个 TransactionManager?这似乎是来自容器的 JCA,但我不明白此决定的机制。
- 我是否应该删除我的 UT 和 TM 并将控制权交给 容器将这些组件提供给我的应用程序并依赖 JTA 平台现状还是我应该尝试获得更多控制权?
最佳答案
容器为数据源提供来自 JCA 的事务管理器。这个 TransactionManager 是一个与我们从 Spring 连接的实例不同的实例。 (我们的 bean 是从 arjuna 环境 bean 实例化的)。使用 Spring 中的 JtaManager 通过默认位置的 JNDI 从容器中获取事务管理器,确保我们在 Hibernate 使用的 JTA 平台(本例中为 JBoss 应用服务器)中拥有相同的事务管理器。
在我们进行此更改之前,应用程序 TransactionManager 与 Hibernate 处于事务中,但数据源上的 transactionManager 未参与,这导致了“泄漏”。
使用同一个实例可以让一切协同工作。这也已在 WebLogic 上使用相同的方法得到了证明。
关于java - 来自 Spring 还是 JNDI 的 TransactionManager? (JBOSS + Spring 3 + Hibernate 4 + JTA),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19166272/