Atomikos Forum

XA + Derby(Embedded) + OSGi + Spring DM + Atomikos essential

Using Knopflerfish + Spring DM, on top of embedded Derby. I have two bundles, one has two methods(one inserts a record and the other method deletes the same record). These two methods have SUPPORTED tx annotation. In another bundle I tried to put these two methods in the same transaction. I use Spring's TX annotation on all the bundles. For some reason it looks like I cannot put them in the same TX context--if I fail the second delete method by throwing a runtime exception the first inserted record still exists, which should be rolled back.

Any high level idea what is going wrong? I can paste the config here if anyone is interested. Thanks a lot!
Jeff Liu Send private email
Sunday, August 30, 2009

Using transactions inside OSGI can be tricky. First, you need global transaction manager. If you plan to use same TX manager in multiple bundles (not your case), you need additional bundle which will expose TX as bean reference, ie:

    <bean id="transactionManagerProvider"
        class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init"
        <property name="forceShutdown" value="true"></property>

    <osgi:service id="transactionManager" interface="javax.transaction.TransactionManager" ref="transactionManagerProvider"/>

    <bean id="userTransactionProvider" class="com.atomikos.icatch.jta.UserTransactionImp"/>

    <osgi:service id="userTransaction" interface="javax.transaction.UserTransaction" ref="userTransactionProvider"/>

And in your bundle(s) you then need:

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

    <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="TransactionManagerServer"></property>
        <property name="userTransaction" ref="UserTransactionServer"></property>

    <osgi:reference id="TransactionManagerServer" interface="javax.transaction.TransactionManager"/>

    <osgi:reference id="UserTransactionServer" interface="javax.transaction.UserTransaction"/>

Only after this, all your bundles will be aware of global transaction manager - otherwise, i guess that thing will broke.

And additional small note - when you annotate class (or method) to be transactional, entering this class/mehod will start transaction, and leaving it will commit it, regardless of previous or later calls. I guess that your first call commit-s it. Additonally, check if runtime exception will actually do rollback - there is option on tx annotation to specify on which exceptions to rollback, and on which to ignore.

Hrvoje Habjanic Send private email
Thursday, September 10, 2009

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics