2
votes

I have been trying to figure this out for two days without sucess. I am using annotation-driven transactions with Spring 3.0.5 and Postgress. I am calling two dao methods from a business logic method:

@Transactional 
public void registerTransaction(GoogleTransaction transaction) {
       long transactionID = DBFactory.getTransactionDBInstance().addTransaction(transaction);
       DBFactory.getGoogleTransactionDBInstance().addGoogleTransaction(transaction, transactionID);

}

The second method (addGoogleTransaction) throws a RuntimeException at the end, however transaction is not rolled back and both rows are inserted.

The DAO method looks like this:

public void addGoogleTransaction(GoogleTransaction transaction, long id) {
    log.trace("Entering addGoogleTransaction DAO method ");
    log.trace(transaction.toString());
    getSimpleJdbcTemplate().update(QRY_ADD_GOOGLE_TRANSACTION, new Object[] {id, transaction.getGoogleSerialNumber() ,
        transaction.getGoogleBuyerID(), transaction.getGoogleOrderID()});
    log.trace("Google transaction added successfully");
    throw new RuntimeException();
}

The Spring configuration file:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven />

Do I need to configure something else? I have tried to add @Transactional to the business logic class and @Transactional to the dao methods but it doesn't work neither. Thanx

It is called from a controller class (annotated with @Controller) for testing pursposes.

@RequestMapping(value = "/registration")
public String sendToRegistrationPage() throws ServiceException {

    GoogleTransaction googleTransaction = new GoogleTransaction(0, "aei", new Date(), TransactionStatus.NEW, BigDecimal.ZERO, "", "", 0, "");
    BillingFactory.getBillingImplementation("").registerTransaction(googleTransaction);
    return "registration";
}
1
Where do you call registerTransaction from? Can you include this code? What classes do these methods belong to? - mrembisz
"however transaction is not rolled back and both rows are inserted." -- wich transaction do you mean: the GoogleTransaction? - Ralph
I added the coded where it is called. Is this important? - Oscar
Dao methods are in a class that inherits SimpleJdbcDaoSupport. The registerTransaction logic method is in a different package and class where all the business logic classes are. - Oscar
Ralph, both transactions are not rolled back. I want that both transactions commit or fail. Thanks - Oscar

1 Answers

1
votes

I'm not quite sure what BillingFactory.getBillingImplementation("") does. Is it a plain Java factory or does ist return a Spring service from the application context? I'm also not sure if you have Spring transactional proxies - if not then what you do is very likely autocommited. I think it'd be a good idea to enable logging for the package org.springframework.transaction.

Actually I'd expect something like:

@Controller
public class MyController {

    @Resource
    private BillingService billingService;

    @RequestMapping(value = "/registration")
    public String sendToRegistrationPage() throws ServiceException {
        GoogleTransaction googleTransaction = new GoogleTransaction(0, "aei", new Date(), TransactionStatus.NEW, BigDecimal.ZERO, "", "", 0, "");
        billingService.registerTransaction(googleTransaction);
        return "registration";
    }
}

And in your Spring config something like (or some @Service annotated bean):

<bean id="billingService" class="foo.bar.BillingImplementation" />