Spring magic - Nested transactions
Ioan Cocan
The problem: Import a large number of items into a database, commiting valid ones and keeping 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 commit if all ok.
Spring solution: Easy, just modifying the transaction demarcation. Along with traditional EJB transaction demarcation startegies, PROPAGATION_NESTED provides the needed behaviour.
Have the descriptor look like:
<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 inner method (importNewItem) will start nested transactions. The programmer can choose to catch inner methods exceptions, thus commiting the outer transaction, or let them propagate, rolling back the outer transaction.
More on nested transactions: http://forum.springframework.org/showthread.php?t=16594.
Posted in Java, General |
No Comments »
