Spring magic – Nested transactions

2 min read >

Spring magic – Nested transactions

Engineering Insights & Enterprise solutions

The problem: Import a large number of items into a database, commit valid ones, and keep track of invalid ones. All in a single transaction.

Traditional solution: Tedious to write. Programatically start a transaction and set a savepoint for each processed item. Rollback to savepoint if an exception occurs or commits if all ok.

Spring solution: Easy, just modifying the transaction demarcation. Along with traditional EJB transaction demarcation strategies, PROPAGATION_NESTED provides the needed behavior.

Have the descriptor look like this:

<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">

<props>
<prop key="import*">PROPAGATION_REQUIRED</prop>



<prop key="importNewItem">PROPAGATION_NESTED, -ImportException</prop>

<prop key="*">PROPAGATION_REQUIRED, readOnly</prop>

</props>
</property>

</bean>

And code like:

void import(){

while( moreToImport) {

try {

importNewItem(item);
imported.add(item);
}catch(ImportException ie){

failed.add(item);
}

}

}

The outer method (import) will start the transaction and the inner method (importNewItem) will start nested transactions. The programmer can choose to catch inner methods exceptions, thus committing the outer transaction, or let them propagate, rolling back the outer transaction.

More on nested transactions: http://forum.springframework.org/showthread.php?t=16594.