Конфигурация Spring JTA TransactionManager:Поддержка как Tomcat, так и JBoss

StackOverflow https://stackoverflow.com/questions/117751

Вопрос

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

У меня работают оба сценария, но теперь я обнаруживаю, что мне, похоже, нужны две отдельные конфигурации Spring для этих двух случаев.С 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 - без необходимости использования двух разных файлов конфигурации?

Это было полезно?

Решение

Я думаю, вы упустили суть 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.strategy=jotm как системное свойство

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

Надеюсь, это поможет.

Если вы используете Spring 2.5, вы можете использовать <tx:jta-transaction-manager />.Я не использовал его с JBoss, но он должен работать у вас в соответствии с разделом 9.8 Интеграция с сервером приложений из справочного руководства Spring.

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top