Milan Čečrdle
12.10.2011

JTA v integračních testech bez aplikačního serveru



JTA tedy distribuované transakce se dost často použivájí v enterprise systémech, kde je potřeba přistupovat jak k více databázím, tak třeba v kombinaci databáze a messaging systém (např. Websphere MQ). Mezi vývojáři obecně panuje představa, že pro jeho využítí potřebuji aplikační server ala Jboss či Websphere, případně také, že bez EJB JTA nelze použít. Toto není samozřejmě pravda a např. pokud použijeme Spring, situace se nám ještě velmi zjednoduší. V příkladu si ukážeme jak nakonfigurovat transakční manager pro test, který otestuje jednu komponentu, ve které je logika přístupu k více XA zdrojům.

Takto vypadá šablona spring integračního testu, který naloaduje aplikační kontexty, jeden s konfigurací aplikace a jeden s konfigurací testovacího JTA manageru.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"/applicationTestContext.xml", "/applicationContext.xml"}) 
@TestExecutionListeners({TransactionalTestExecutionListener.class}) 
@Transactional
public class JTASampleIntegrationTest extends AbstractJUnit4SpringContextTests {
  @Test
  public void testComponenet() { } 
} 


Existuje více implementací JTA, například Atomikos nebo Jotm. Pro testy jsem se rozhodl použít Jotm implementace a dále implementaci XA pool datasource z projektu Enhydra XAPool. Prvni co musíme je definovat JTATransactionManagera. Tomu musíme specifikovat referenci na factory, která vytvoří JOTM objekt, který implementuje UserTransaction interface. Pro JOTM je již factory součastí springu. V případě běhu v aplikačním server už má JTATransactionManager implementován automatický lookup do JNDI pro konkrétní objekt a není třeba specifikovat nic.

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


Takto nadefinujeme „testDataSource1“ s využitím XA datasource z Enhrydry, obdobně definuje i druhý datasource.

<bean id="testDataSource1" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
  <property name="dataSource">
    <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
      <property name="transactionManager">
        <ref local="jotm" />
      </property>
      <property name="driverName">
        <value>com.informix.jdbc.IfxDriver</value>
      </property>
      <property name="url" value="jdbc:informix-sqli://....."/>
    </bean>
  </property>
  <property name="user">
    <value>user</value>
  </property>
  <property name="password">
    <value>password</value>
  </property>
</bean>


Pak už pouze spustíme test a ověříme, že změny v obou datasourcech při testech nebyly commitnuty.

Vaše emailová adresa nebude zveřejněna

Komentáře

Děkujeme za váš komentář
Další