MyBatis-Spring setup not using transactions

holic87 picture holic87 · Nov 18, 2011 · Viewed 10.2k times · Source

I have a web application set up with MyBatis and Spring, but it doesn't seem to be using any transactions. Here's the configuration:

applicationContext.xml:

<tx:annotation-driven />

<!-- <tx:jta-transaction-manager /> --> <!-- using WebSphere 7 -->

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

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/my_datasource" />
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="configLocation" value="WEB-INF/mybatis-config.xml" />
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="testDAO" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="com.lmig.TestDAO" />
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

Sample bean method with transaction definition:

@Transactional(propagation = Propagation.REQUIRED)
public void testDelete() {
    testDAO.firstDelete(); //always successful
    testDAO.secondDelete(); //always throws SQLServerException
}

TestDAO:

public interface TestDAO {
    public void firstDelete();
    public void secondDelete();
}

Server debug log:

[11/17/11 16:42:07:998 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Creating SqlSession with JDBC Connection [com.ibm.ws.rsadapter.jdbc.WSJdbcConnection@34ba34ba] 
[11/17/11 16:42:07:999 PST] 0000002b SystemOut     O DEBUG [java.sql.Connection] ooo Connection Opened 
[11/17/11 16:42:08:001 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] JDBC Connection [com.ibm.ws.rsadapter.jdbc.WSJdbcConnection@34ba34ba] will be managed by Spring 
[11/17/11 16:42:08:005 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74247424] 
[11/17/11 16:42:08:025 PST] 0000002b SystemOut     O DEBUG [java.sql.PreparedStatement] ==>  Executing: delete from test1  
[11/17/11 16:42:08:025 PST] 0000002b SystemOut     O DEBUG [java.sql.PreparedStatement] ==> Parameters:  
[11/17/11 16:42:08:097 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74247424] 
[11/17/11 16:42:08:099 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74247424] 
[11/17/11 16:42:08:123 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74247424] 
[11/17/11 16:42:08:136 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Creating SqlSession with JDBC Connection [com.ibm.ws.rsadapter.jdbc.WSJdbcConnection@17351735] 
[11/17/11 16:42:08:137 PST] 0000002b SystemOut     O DEBUG [java.sql.Connection] ooo Connection Opened 
[11/17/11 16:42:08:138 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] JDBC Connection [com.ibm.ws.rsadapter.jdbc.WSJdbcConnection@17351735] will be managed by Spring 
[11/17/11 16:42:08:139 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1d871d87] 
[11/17/11 16:42:08:145 PST] 0000002b SystemOut     O DEBUG [java.sql.PreparedStatement] ==>  Executing: delete from test2  
[11/17/11 16:42:08:146 PST] 0000002b SystemOut     O DEBUG [java.sql.PreparedStatement] ==> Parameters:
[11/17/11 16:42:08:490 PST] 0000002b XmlBeanDefini I org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
[11/17/11 16:42:08:554 PST] 0000002b SQLErrorCodes I org.springframework.jdbc.support.SQLErrorCodesFactory <init> SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
[11/17/11 16:42:08:560 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1d871d87] 
[11/17/11 16:42:08:597 PST] 0000002b SystemOut     O DEBUG [org.mybatis.spring.SqlSessionUtils] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1d871d87]
...SQLServerException follows...

Since secondDelete() throws an exception, the entire transaction would be expected to roll back. However, this isn't the case, and the firstDelete() is still committed. I've tried all combinations of the transaction manager config (Spring-managed, app server-managed, both) but I keep getting the same results. Any idea what I'm doing wrong?

I'm using Mybatis 3, Spring 3 on WebSphere 7 with SQL Server 2005 as the DB.

Answer

holic87 picture holic87 · Nov 18, 2011

I figured this out: my testDelete() method wasn't a Spring-managed bean, so it wasn't participating in Spring-managed transactions. I changed my configuration to this, and now it's working.