Domanda

Ho un'applicazione web che utilizza JPA e JTA con Spring. Vorrei supportare sia JBoss che Tomcat. Quando corro su JBoss, mi piacerebbe usare il TransactionManager di JBoss e, quando corro su Tomcat, mi piacerebbe usare JOTM.

Ho entrambi gli scenari funzionanti, ma ora scopro di aver bisogno di due configurazioni Spring separate per i due casi. Con JOTM, devo usare Spring JotmFactoryBean:

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

In JBoss, tuttavia, devo solo recuperare " TransactionManager " da 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>

Esiste un modo per configurarlo in modo che venga utilizzato il TransactionManager appropriato - JBoss o JOTM - senza la necessità di due diversi file di configurazione?

È stato utile?

Soluzione

Penso che tu abbia perso il punto di JNDI. JNDI è stato praticamente scritto per risolvere il problema che hai!

Penso che tu possa salire di livello, quindi invece di usare " userTransaction " oppure " ;actionManager da JNDI " a seconda della situazione. Perché non aggiungere il & Quot; JtaTransactionManager & Quot; a JNDI. In questo modo spingi la configurazione su JNDI dove dovrebbe essere invece di creare ancora più file di configurazione [come se non ce ne fossero già abbastanza;)].

Altri suggerimenti

È possibile utilizzare PropertyConfigurerPlaceholder per iniettare riferimenti bean e valori semplici.

Ad esempio, se chiami i tuoi bean "jotm" e "jboss", puoi iniettare la tua TM come:

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

Quindi puoi scambiare i gestori delle transazioni usando

  • transaction.strategy = jotm in un file delle proprietà
  • -Dtransaction.strategy = jotm come proprietà di sistema

Questo è un possibile approccio. Vedi il mio blog per un esempio più completo .

Spero che questo aiuti.

Se stai usando Spring 2.5 puoi usare < tx: jta-transaction-manager / > ;. Non l'ho usato con JBoss ma dovrebbe funzionare secondo la sezione 9.8 Integrazione specifica del server delle applicazioni dal manuale di riferimento di Spring.

L'approccio <tx:jta-transaction-manager/> cercherà un gestore delle transazioni in diverse posizioni predefinite elencato qui . Se il gestore delle transazioni JBoss non si trova in una di quelle posizioni, ti suggerisco di spostarlo, se possibile, o spostarlo in Tomcat in modo che entrambi i contenitori abbiano la loro TM nella stessa posizione JNDI.

Sto solo aggiungendo la mia esperienza qui, quindi non devo risentirla di nuovo.

Come hanno detto bmatthews68, Chochos e questi poster , usano <tx:jta-transaction-manager/> nel tuo file Spring bean; fornisce sicuramente il livello appropriato di astrazione e non è necessario fare nulla in più sul lato Spring.

Per quanto riguarda Tomcat, ho dichiarato <Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60" /> nel file conf/context.xml predefinito / condiviso, che si lega a java:comp/UserTransaction. Dato che questo è uno dei luoghi cercati da Spring, non dovresti fare nient'altro.

Un gotcha però: se come me usi Maven, assicurati di escludere eventuali dipendenze dal vaso javax.transaction:jta o imposta l'ambito su provided. Altrimenti riscontrerai problemi con il classloader.

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