Tuesday, December 20, 2005

Transaction Management with iBATIS and Spring

For Othon Sanchez, who wrote:

I'm trying to implement ibatis, spring and JSF. Not so hard until now but I have a special requirement, I need to handle the transaction in a EXTERNAL way, like the documentation of iBatis suggests. My question is, do you know how I can implement iBatis and Spring handling by my own the transaction?. Do I need to configure something else in the applicationContext.xml or dataAccessContext-xxx.xml?.

I have to admit that I know very little about transaction management as I have only recently learnt about Spring and iBATIS myself. Since I haven't actually done this yet, what follows is completely guess work (comments from the more experienced and learned are always very welcome).

Spring apparently provides it's own transaction management capability which looks to me like it works with iBATIS. In the API docs for SqlMapClientFactoryBean there are several mentions of transaction management. There is a method setUseTransactionAwareDataSource() where it says something about using Spring's managed transactions by default.

It also says it uses iBATIS EXTERNAL style transaction management by default (com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig). Incidentally, there are also methods available that can be used to set transactionConfigClass and transactionConfigProperties (see also here).

To actually use transaction management the following is what I would think you need to do (this is complete guess work on my part). This is based upon the synthesis of Spring Chapter 8. Transaction management and Faster, Lighter, Better?: Spring time for J2EE by Björn Beskow [PDF]).

In your applicationContext.xml you would define your datasource, datasource proxy, transaction manager as well as all your other DAO bits and pieces (as I showed previously in an iBATIS related entry). Additionally, I would now also expect that you would inject the transactionManager bean into the DAO implementation. So the XML configuration file might look something like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="dataSourceImpl" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>org.apache.derby.jdbc.EmbeddedDriver</value>
</property>
<property name="url">
<value>jdbc:derby:build/derby/simpledb</value>
</property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<property name="targetDataSource">
<ref local="dataSourceImpl"/>
</property>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="dataSourceImpl"/></property>
</bean>

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation"><value>sqlmap-config.xml</value></property>
</bean>

<bean id="itemDAO" class="mypackage.sqlmapdao.SqlMapItemDao">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="sqlMapClient"><ref local="sqlMapClient"/></property>
<property name="transactionManager"><ref local="transactionManager"/></property>
</bean>

<bean id="facade" class="mypackage.domain.logic.FacadeImpl">
<property name="itemDao"><ref local="itemDAO"/></property>
</bean>

</beans>

Then in order to do programmatic transaction management in your DAO implementation you could create transaction managed methods using Spring's TransactionTemplates. There are other ways that you can do transaction management more directly using the PlatformTransactionManager or even less directly using AOP for declarative transaction management, further instructions can be found in Spring Chapter 8: Transaction management:


TransactionTemplate txTemplate =
new TransactionTemplate(txManager);
Object result = txTemplate.execute(
new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
// Do some work on a transactional resource
// Return some result object or throw an unchecked exception
}
);

5 comments:

Mark McLaren said...

Hi Mark



Thanks for this article, it bring me some good ideas that i can try to make spring work with ibatis in the way that i need. The bad new is that i have no time to try it.

Anyway, as soon as i can do something i write you a comment.



Once again thank you
Note: Comment imported. Original by Othon Sanchez at 2005-12-21 14:41

Mark McLaren said...

Hey!!!!!!!!! it works. thanks a lot it works!!!!!. I use the programmatic transaction management as you suggest and now i have spring working with iBatis as i need it.

Thanks, thanks and thanks a lot!!!!!!!.



By the way. Happy Christmas!!!!!!!!!
Note: Comment imported. Original by Othon Sanchez at 2005-12-23 23:35

Mark McLaren said...

Hi ,

Thanx for the nice explantion. Can u please explain , how i can integrate Spring , Session Bean and Dao (Spring provided DAO framework ).The requirement is session bean takes care of the transactions , sprint takes care of the IOC and the dao will do the persistence logic. i am facing partial commit problem , as ibatis implictly commits the transaction for every sql statement execution.
Note: Comment imported. Original by Srinivas jill at 2007-03-14 18:47

Mark McLaren said...

I am afraid I know very little about Session beans (I assume you are referring to EJB?). I would guess that the DAO/transaction layer should in an identical way to any other Spring managed transaction processing (as described above). For further assistance, I found another example on the Spring forums that may be helpful to you: Spring programmatic transactions.


Note: Comment imported. Original by markmc website: http://content.mark-mclaren.info/ at 2007-03-14 23:20

Picassa said...

Thanks a ton...
Its works fine...
Once again thanks for sharing this..