Java Spring JTA TransactionManager 配置:同时支持 Tomcat 和 JBoss
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/117751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring JTA TransactionManager config: Supporting both Tomcat and JBoss
提问by Henning
I have a web application using JPA and JTA with Spring. I would like to support both JBoss and Tomcat. When running on JBoss, I'd like to use JBoss' own TransactionManager, and when running on Tomcat, I'd like to use JOTM.
我有一个使用 JPA 和 JTA 和 Spring 的 Web 应用程序。我想同时支持 JBoss 和 Tomcat。在 JBoss 上运行时,我想使用 JBoss 自己的 TransactionManager,而在 Tomcat 上运行时,我想使用 JOTM。
I have both scenarios working, but I now find that I seem to need two separate Spring configurations for the two cases. With JOTM, I need to use Spring's JotmFactoryBean
:
我有两种方案都可以使用,但我现在发现对于这两种情况,我似乎需要两个单独的 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>
In JBoss, though, I just need to fetch "TransactionManager" from JNDI:
但是,在 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>
Is there a way to configure this so that the appropriate TransactionManager - JBoss or JOTM - is used, without the need for two different configuration files?
有没有办法配置它以便使用适当的 TransactionManager - JBoss 或 JOTM - 而不需要两个不同的配置文件?
采纳答案by David Newcomb
I think you have missed the point of JNDI. JNDI was pretty much written to solve the problem you have!
我认为您错过了 JNDI 的重点。JNDI 几乎是为解决您遇到的问题而编写的!
I think you can take it up a level, so instead of using the "userTransaction" or "transactionManager from JNDI" depending on your situation. Why not add the "JtaTransactionManager" to JNDI. That way you push the configuration to the JNDI where it is supposed to be instead of creating even more configuration files [ like there aren't enough already ;) ].
我认为您可以将其提升一个级别,因此不要根据您的情况使用“userTransaction”或“JNDI 的transactionManager”。为什么不将“JtaTransactionManager”添加到 JNDI。这样您就可以将配置推送到 JNDI 应该在的位置,而不是创建更多的配置文件 [就像没有足够的配置文件 ;) ]。
回答by toolkit
You can use PropertyConfigurerPlaceholder to inject bean references as well as simple values.
您可以使用 PropertyConfigurerPlaceholder 来注入 bean 引用以及简单的值。
For example if you call your beans 'jotm' and 'jboss' then you could inject your TM like:
例如,如果您将 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>
Then you can swap transaction managers using
然后你可以使用交换事务管理器
- transaction.strategy=jotmin a properties file
- -Dtransaction.strategy=jotmas a system property
- 属性文件中的transaction.strategy=jotm
- -Dtransaction.strategy=jotm作为系统属性
This is one possible approach. See my blogfor a more complete example.
这是一种可能的方法。有关更完整的示例,请参阅我的博客。
Hope this helps.
希望这可以帮助。
回答by Brian Matthews
If you are using Spring 2.5 you can use <tx:jta-transaction-manager/>. I have not used it with JBoss but it should work for you according to section 9.8 Application server-specific integrationfrom the Spring reference manual.
如果您使用的是 Spring 2.5,则可以使用 <tx:jta-transaction-manager/>。我没有将它与 JBoss 一起使用,但根据Spring 参考手册中的第9.8节应用程序服务器特定的集成,它应该对您有用。
回答by Chochos
The <tx:jta-transaction-manager/>
approach will look for a transaction manager in several default locations listed here. If your JBoss transaction manager is not in one of those locations, I suggest you move it, if possible, or move it in Tomcat so that both containers have their TM in the same JNDI location.
该<tx:jta-transaction-manager/>
方法将在此处列出的几个默认位置查找事务管理器。如果您的 JBoss 事务管理器不在这些位置之一,我建议您尽可能地移动它,或者将它移动到 Tomcat 中,以便两个容器在同一个 JNDI 位置拥有它们的 TM。
回答by Darren Bishop
Just adding my experience here so I don't have to re-suffer the experience again.
只是在这里添加我的经验,这样我就不必再次遭受这种经历。
As bmatthews68, Chochos and these postershave said, use <tx:jta-transaction-manager/>
in your Spring bean file; it definitely provides the appropriate level of abstraction and there's no need to do anything extra on the Spring side.
正如 bmatthews68、Chochos 和这些海报所说,<tx:jta-transaction-manager/>
在你的 Spring bean 文件中使用;它绝对提供了适当的抽象级别,并且不需要在 Spring 端做任何额外的事情。
As for Tomcat, I declared <Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60" />
in the default/shared conf/context.xml
file, which binds to java:comp/UserTransaction
. As this is one of the places searched for by Spring, you shouldn't need to do anything else.
至于 Tomcat,我<Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60" />
在默认/共享conf/context.xml
文件中声明,该文件绑定到java:comp/UserTransaction
. 由于这是 Spring 搜索的位置之一,因此您不需要执行任何其他操作。
One gotcha though: if like me you use Maven, make sure you exclude any dependencies on the javax.transaction:jta
jar or set the scope to provided
. Otherwise you will experience classloader issues.
不过有一个问题:如果像我一样使用 Maven,请确保排除对javax.transaction:jta
jar 的任何依赖项或将范围设置为provided
. 否则,您将遇到类加载器问题。