Domanda

Ho un file applicationContext.xml e ha due org.springframework.orm.jpa.JpaTransactionManager (ciascuno con la propria unità di persistenza, database diversi) configurati in un'applicazione personalizzata middleware Spring.

Desidero utilizzare transazioni basate su annotazioni (@Transactional), per non scherzare con il commit, il salvataggio e il rollback di TransactionStatus.

Un collega ha affermato che si crea confusione in questo caso quando sono presenti più gestori di transazioni, anche se il file di contesto è configurato correttamente (i riferimenti vanno all'unità di persistenza corretta.Qualcuno ha mai riscontrato un problema?


Nella tua configurazione, avresti due gestori delle transazioni?Avresti txManager1 e txManager2?

Questo è quello che ho con JPA, due diversi bean Spring che sono gestori di transazioni.

È stato utile?

Soluzione

Immagino che tu abbia 2 scelte

Se i tuoi casi d'uso non richiedono mai aggiornamenti a entrambi i database all'interno della stessa transazione, puoi utilizzare due JpaTransactionManagers, ma non sono sicuro che sarai in grado di utilizzare l'approccio @Transactional?In questo caso, dovresti ricorrere al vecchio meccanismo di utilizzo di un semplice TransactionProxyFactoryBean per definire i confini della transazione, ad esempio:

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

Se hai bisogno di una transazione che si estende su entrambi i database, dovrai utilizzare un gestore transazioni JTA.IL API stati:

Questo gestore transazioni è appropriato per le applicazioni che utilizzano un singolo EntityManagerFactory JPA per l'accesso ai dati transazionali.JTA (solitamente tramite JtaTransactionManager) è necessario per accedere a più risorse transazionali all'interno della stessa transazione.Tieni presente che devi configurare di conseguenza il tuo provider JPA per renderlo partecipe delle transazioni JTA.

Ciò significa che dovrai fornire un gestore delle transazioni JTA.Nella nostra applicazione, utilizziamo una configurazione simile alla seguente:

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

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

Se si esegue la distribuzione all'interno di un appserver, il JtaTransactionManager primaverile deve eseguire una ricerca sul vero gestore delle transazioni JTA conforme a XA fornito dall'appserver.Tuttavia, puoi anche utilizzare un gestore di transazioni JTA autonomo (ma non l'ho ancora provato personalmente)

Per quanto riguarda la configurazione del provider di persistenza Jpa, non ho molta familiarità.Quale provider di persistenza JPA stai utilizzando?

Il codice riportato sopra si basa sul nostro approccio, in cui utilizzavamo Hibernate nativo anziché l'implementazione JPA di Hibernate.In questo caso, siamo riusciti a sbarazzarci dei due bean HibernateTransactionManager e semplicemente assicurarci che entrambe le SessionFactory fossero iniettate con lo stesso JTA TM, quindi utilizzare l'elemento tx:annotation-driven.

Spero che questo ti aiuti

Altri suggerimenti

L'unica situazione in cui puoi avere due gestori di transazioni Spring è se non hai mai entrambe le transazioni aperte contemporaneamente.Ciò non ha a che fare intrinsecamente con le transazioni distribuite: le stesse restrizioni si applicano anche se si desidera che le due origini dati abbiano cicli di vita delle transazioni completamente separati (ma potenzialmente sovrapposti nel tempo).

Internamente i gestori delle transazioni di Spring utilizzano tutti TransactionSynchronizationManager di Spring che mantiene un sacco di stati critici in variabili statiche ThreadLocal, in modo che i gestori delle transazioni abbiano la garanzia di calpestare lo stato degli altri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top