Spring JTA TransactionManager config: поддержка Tomcat и JBoss

у меня есть веб-приложение, использующее JPA и JTA с Spring. Я хотел бы поддержать как JBoss и Tomcat. При работе на JBoss я хотел бы использовать собственный TransactionManager JBoss, а при работе на Tomcat я хотел бы использовать JOTM.

у меня работают оба сценария, но теперь я нахожу, что мне нужны две отдельные конфигурации пружин для двух случаев. С JOTM мне нужно использовать Spring's JotmFactoryBean:

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

в JBoss, хотя, мне просто нужно принести "TransactionManager" от JNDI:

<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 - без необходимости использования двух разных файлов конфигурации?

5 ответов


Я думаю, что вы пропустили точку JNDI. JNDI был в значительной степени написан, чтобы решить проблему, которую вы имеете!

Я думаю, вы можете поднять его на уровень, поэтому вместо использования "userTransaction" или "transactionManager от JNDI" в зависимости от вашей ситуации. Почему бы не добавить "JtaTransactionManager" в JNDI. Таким образом, вы нажимаете конфигурацию на JNDI, где она должна быть, вместо того, чтобы создавать еще больше файлов конфигурации [ как будто их уже недостаточно ;) ].


вы можете использовать PropertyConfigurerPlaceholder для ввода ссылок на компоненты, а также простых значений.

например, если вы называете свои бобы "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>

затем вы можете поменять менеджеров транзакций с помощью

  • сделки.стратегия=jotm в свойствах файла
  • - Dtransaction.стратегия=jotm как системное свойство

Это один возможный подход. Смотрите мой блог для более полного примера.

надеюсь, что это помогает.


Если вы используете Spring 2.5, вы можете использовать . Я не использовал его на JBoss, но он должен работать для вас в соответствии с разделом 9.8 интеграция с сервером приложений из справочного руководства Spring.


на <tx:jta-transaction-manager/> подход будет искать менеджер транзакций в нескольких местах по умолчанию перечисленные здесь. Если ваш менеджер транзакций JBoss не находится в одном из этих местоположений, я предлагаю вам переместить его, если это возможно, или переместить его в Tomcat, чтобы оба контейнера имели свои TM в одном местоположении JNDI.


просто добавляя свой опыт здесь, чтобы мне не пришлось снова страдать от этого опыта.

как bmatthews68, Chochos и эти плакаты сказали, используйте <tx:jta-transaction-manager/> в вашем файле Spring bean; он определенно обеспечивает соответствующий уровень абстракции, и нет необходимости делать что-либо дополнительное на стороне Spring.

что касается кота, я заявил <Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60" /> по умолчанию / shared conf/context.xml файл, который привязывается к java:comp/UserTransaction. Так как это одно из мест для поиска Спринг, тебе не нужно больше ничего делать.

One gotcha though: если, как и я, вы используете Maven, убедитесь, что вы исключаете любые зависимости от javax.transaction:jta jar или установите область в provided. В противном случае вы столкнетесь с проблемами classloader.