Domanda

I have a simple standalone application to test transaction management with Spring. Have Oracle Express Edition. Run the following to enable XA

grant select on sys.dba_pending_transactions to user_test;
grant select on sys.pending_trans$ to user_test;
grant select on sys.dba_2pc_pending to user_test;
grant execute on sys.dbms_system to user_test;

My Java code is pretty much as follow:

public class DbUpdater 
{
    private static final ApplicationContext context = 
       new ClassPathXmlApplicationContext(new String[] {"spring_transactions.xml"});
    private static Logger log = LoggerFactory.getLogger(DbUpdater.class);

    @Transactional(propagation=Propagation.REQUIRED, readOnly=false)
    public void updateData()  {
        IMasterDAO ds1 = context.getBean("masterDao", IMasterDAO.class);
        log.info("Insert using ds1");
        ds1.insert("insert into users values(?,?)", "user1", "John Hamilton");
        log.info("Insert using ds1 finished successfully");

        throw new RuntimeException("A runtime exception");
    }
}

So all the idea is too see transaction rolling back. I run with several configuration examples and record is committed all the time. No rollback is performed. No errors nothing, only expected

Exception in thread "main" java.lang.RuntimeException: A runtime exception
at com.test.spring.transation.DbUpdater.updateData(DbUpdater.java:22)

My last config is this:

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

    <bean id="btmConfig" factory-method="getConfiguration"
         class="bitronix.tm.TransactionManagerServices">
         <property name="serverId" value="spring-btm" />
    </bean>

    <bean id="bitronixTransactionManager" factory-method="getTransactionManager"
        class="bitronix.tm.TransactionManagerServices" 
                depends-on="btmConfig,dataSource"
        destroy-method="shutdown" />

    <bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" 
      init-method="init" destroy-method="close">
    <property name="className" value="oracle.jdbc.xa.client.OracleXADataSource"/>
    <property name="uniqueName" value="myOracleDataSource"/>
    <property name="minPoolSize" value="0"/>
    <property name="maxPoolSize" value="5"/>
    <property name="allowLocalTransactions" value="true"/>
    <property name="testQuery" value="select sysdate from dual"/>
    <property name="driverProperties">
        <props>
            <prop key="user">${jdbc.username}</prop>
            <prop key="password">${jdbc.password}</prop>
            <prop key="URL">${jdbc.url}</prop>
        </props>
    </property>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<bean id="masterDao" class="com.test.spring.transation.MasterDAO">
    <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>

</beans>
È stato utile?

Soluzione

The JDBC template being instantiated via supplied data source, seems to work with its own transaction [there by the automatic begin and commit transaction]. The exception is thrown after that which operates in seperate commit/rollback cycle and hence you see that the writes persisted. To verify it, you can move the code to throw exception in MasterDAO class and examine rollback.

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