Pregunta

Tengo un archivo applicationContext.xml y tiene dos org.springframework.orm.jpa.JpaTransactionManager (cada uno con su propia unidad de persistencia y diferentes bases de datos) configurados en una aplicación personalizada de middleware Spring.

Quiero usar transacciones basadas en anotaciones (@Transactional), para no perder el tiempo con la confirmación, el guardado y la reversión de TransactionStatus.

Un compañero de trabajo mencionó que algo se confunde al hacer esto cuando hay varios administradores de transacciones, a pesar de que el archivo de contexto está configurado correctamente (las referencias van a la unidad de persistencia correcta).¿Alguien ha visto alguna vez un problema?


En su configuración, ¿tendría dos administradores de transacciones?¿Tendrías txManager1 y txManager2?

Eso es lo que tengo con JPA, dos Spring beans diferentes que son administradores de transacciones.

¿Fue útil?

Solución

Supongo que tienes 2 opciones

Si sus casos de uso nunca requieren actualizaciones de ambas bases de datos dentro de la misma transacción, entonces puede usar dos JpaTransactionManagers, pero no estoy seguro de que pueda usar el enfoque @Transactional.En este caso, necesitará recurrir al mecanismo anterior de utilizar un simple TransacciónProxyFactoryBean para definir los límites de las transacciones, por ejemplo:

<bean id="firstRealService" class="com.acme.FirstServiceImpl"/>
<bean id="firstService"  
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="firstJpaTm"/>
    <property name="target" ref="firstRealService"/>
    <property name="transactionAttributes">
        <props>
           <prop key="insert*">PROPAGATION_REQUIRED</prop>
           <prop key="update*">PROPAGATION_REQUIRED</prop>
           <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>
<!-- similar for your second service -->

Si necesita una transacción que abarque ambas bases de datos, deberá utilizar un administrador de transacciones JTA.El API estados:

Este administrador de transacciones es apropiado para aplicaciones que utilizan una única JPA EntityManagerFactory para el acceso a datos transaccionales.JTA (normalmente a través de JtaTransactionManager) es necesario para acceder a múltiples recursos transaccionales dentro de la misma transacción.Tenga en cuenta que debe configurar su proveedor JPA en consecuencia para que pueda participar en las transacciones JTA.

Lo que esto significa es que deberá proporcionar un administrador de transacciones JTA.En nuestra aplicación, utilizamos una configuración similar a la siguiente:

<tx:annotation-driven transaction-manager="txManager"/>

<bean id="txManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManagerName" value="appserver/jndi/path" />
</bean>

Si está implementando dentro de un servidor de aplicaciones, entonces el JtaTransactionManager de primavera debe realizar una búsqueda en el administrador de transacciones JTA real compatible con XA proporcionado por el servidor de aplicaciones.Sin embargo, también puede utilizar un administrador de transacciones JTA independiente (pero yo todavía no lo he probado)

En cuanto a la configuración del proveedor de persistencia Jpa, no estoy tan familiarizado.¿Qué proveedor de persistencia JPA estás utilizando?

El código anterior se basa en nuestro enfoque, donde usábamos Hibernate nativo en lugar de la implementación JPA de Hibernate.En este caso, pudimos deshacernos de los dos beans HibernateTransactionManager y simplemente asegurarnos de que ambas SessionFactories fueran inyectadas con el mismo JTA TM y luego usar el elemento tx:annotation-driven.

Espero que esto ayude

Otros consejos

La única situación en la que puede tener dos administradores de transacciones Spring es si nunca tiene ambas transacciones abiertas al mismo tiempo.Esto no tiene que ver intrínsecamente con las transacciones distribuidas: se aplican las mismas restricciones incluso si desea que las dos fuentes de datos tengan ciclos de vida de transacciones completamente separados (pero potencialmente superpuestos en el tiempo).

Internamente, todos los administradores de transacciones de Spring usan TransactionSynchronizationManager de Spring, que mantiene un montón de estados críticos en variables estáticas ThreadLocal, por lo que se garantiza que los administradores de transacciones pisotearán el estado de los demás.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top