Spring JTA TransactionManager配置:同时支持Tomcat和JBoss

时间:2020-03-06 14:34:01  来源:igfitidea点击:

我有一个将JPA和JTA与Spring结合使用的Web应用程序。我想同时支持JBoss和Tomcat。在JBoss上运行时,我想使用JBoss自己的TransactionManager,而在Tomcat上运行时,我想使用JOTM。

我可以同时使用这两种方案,但现在发现这两种情况似乎需要两个单独的Spring配置。使用JOTM,我需要使用Spring的JotmFactoryBean

<bean id="transactionManager" 
 class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="userTransaction">
        <bean class="org.springframework.transaction.jta.JotmFactoryBean"/>
    </property>
</bean>

但是,在JBoss中,我只需要从JNDI获取" TransactionManager":

<bean id="transactionManager" 
 class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager">
        <bean class="org.springframework.jndi.JndiObjectFactoryBean">
             <property name="resourceRef" value="true" />
             <property name="jndiName" value="TransactionManager" />
             <property name="expectedType" 
               value="javax.transaction.TransactionManager" />
        </bean>
    </property>
</bean>

有没有一种方法可以配置它,以便使用适当的TransactionManager JBoss或者JOTM,而无需两个不同的配置文件?

解决方案

我们可以使用PropertyConfigurerPlaceholder注入bean引用以及简单值。

例如,如果我们将bean称为" jotm"和" jboss",则可以像以下那样注入TM:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE">
    <property name="location" value="classpath:/path/to/application.properties"/>
</bean>
<bean id="jotm">...</bean>
<bean id="jboss">...</bean>
<bean id="bean-requiring-transaction-manager">
    <property name="transactionManager" ref="${transaction.strategy}"/>
</bean>

然后,我们可以使用以下方法交换交易管理器

  • 属性文件中的transaction.strategy = jotm
  • -Dtransaction.strategy = jotm作为系统属性

这是一种可能的方法。有关更多完整示例,请参见我的博客。

希望这可以帮助。

如果我们使用的是Spring 2.5,则可以使用<tx:jta-transaction-manager />。我没有在JBoss中使用它,但是它应该根据Spring参考手册中的9.8节特定于应用程序服务器的集成为我们工作。

&lt;tx:jta-transaction-manager />方法将在此处列出的几个默认位置中寻找事务管理器。如果JBoss事务管理器不在这些位置之一,我建议我们尽可能移动它,或者在Tomcat中移动它,以便两个容器的TM都在相同的JNDI位置。

我认为我们已经错过了JNDI的重点。 JNDI是为解决我们遇到的问题而编写的!

我认为我们可以将其提高一个级别,所以根据情况,而不是使用" userTransaction"或者" JNDI的事务管理器"。为什么不将" JtaTransactionManager"添加到JNDI。这样,我们可以将配置推送到应该存在的JNDI,而不是创建更多的配置文件[好像还没有足够的;)]。