dsw88
dsw88

Reputation: 4592

Spring - Transaction not being applied around method

I'm trying to use a declarative transaction around a method in my application that makes several database calls. I did that by applying the @Transactional annotation to the method in question, which looks something similar to this:

@Transactional
public MyReturnType myTransactionalMethod(SomeType1 param) {
    SomeType2 someIntermediateObject = dao1.doStuff(param);
    MyReturnType retObj = dao2.doMoreStuff(someIntermediateObject);
    return retObj;
}

I then set up Spring Transactions in my XML config:

<tx:annotation-driven transaction-manager="transactionManager" order="200"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
      p:dataSource-ref="dataSource"/>

I then wanted to test that method to verify that the transactions would rollback correctly on a failure in the method, so I modified my method to look something like this:

public MyReturnType myTransactionalMethod(SomeType1 param) {
    SomeType2 someIntermediateObject = dao1.doStuff(param);
    MyReturnType retObj = dao2.doMoreStuff(someIntermediateObject);
    throw new RuntimeException(); //The RuntimeException should trigger a rollback
}

When I executed this second method, it did not do a rollback like I would expect, but rather it left the created entries in my database. I was also expecting to see in the stack trace some sign of the spring aspect hooks around my method inserted that would handle the transactional stuff, but I only see the calling method immediately before this transactional method, with no sign of any Spring-injected methods.

Can anyone see anything I'm doing wrong that would cause this behavior where the transaction handling doesn't get applied?

Upvotes: 0

Views: 753

Answers (1)

reos
reos

Reputation: 8324

This behavior is because you're using DataSourceTransactionManager, this txManager is used for JDBC transactions. For example, if you insert something in the database and this fails it will rollback this transaction. The tx can fail if you try to insert a value longer than permitted. Notice that the datasource is aware of the failure.

In your example the DataSource is not aware of the failure because you're throwing the exception. For these cases you can use JtaTransactionManager but your container must support JTA Transactions. Or you can make the failure in the database trying to insert some value too long or a value of a different type or a null value in a non-null column.

You can see more here:

http://www.journaldev.com/2603/spring-transaction-management-jdbc-example

http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html

Upvotes: 1

Related Questions