Spring JTA TransactionManager config: Supporting both Tomcat and JBoss

后端 未结 5 1031
广开言路
广开言路 2021-02-06 01:19

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, an

相关标签:
5条回答
  • 2021-02-06 01:48

    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 integration from the Spring reference manual.

    0 讨论(0)
  • 2021-02-06 01:55

    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.

    0 讨论(0)
  • 2021-02-06 01:55

    Just adding my experience here so I don't have to re-suffer the experience again.

    As bmatthews68, Chochos and these posters have 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.

    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.

    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.

    0 讨论(0)
  • 2021-02-06 01:59

    I think you have missed the point of JNDI. JNDI was pretty much written to solve the problem you have!

    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 ;) ].

    0 讨论(0)
  • 2021-02-06 02:06

    You can use PropertyConfigurerPlaceholder to inject bean references as well as simple values.

    For example if you call your beans 'jotm' and 'jboss' then you could inject your TM like:

    <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=jotm in a properties file
    • -Dtransaction.strategy=jotm as a system property

    This is one possible approach. See my blog for a more complete example.

    Hope this helps.

    0 讨论(0)
提交回复
热议问题