When using transation on Mybatis, there are 3 ways.
- Container managed transaction – JEE engine manages transaction
- User managed transaction – transaction is controlled by user source code
- Spring managed transaction – transaction is controlled by Spring Transaction policy
I usually use Spring managed or container managed transaction. But sometimes, I need to control transaction in source code. For example, in case when I need to commit every 100 records, Spring or Container managed transaction is not enough.
SqlSession is the wrapper for JDBC connection, and the core method to change auto commit mode is as follows.
public interface SqlSessionFactory { SqlSession openSession(boolean autoCommit); }
After generating SqlSession by calling SqlSessionFactory.openSession(false), we can handle transaction by SqlSession.commit() or rollback().
But there are some rules on deciding auto commit mode.
- If SqlSessionFactory is generated by SqlSessionFactoryBuilder.build() and transactionManager is set as “JDBC“, then openSession(autoCommit) takes effect (transactionManager is set at config.xml)
- If SqlSessionFactory is generated by SqlSessionFactoryBean.build() and transactionManager is “MANGED“, then underlying container’s auto commit mode takes effect. (autoCommit param in openSession() is ignored)
- If SqlSessionFactory is generated by org.mybatis.spring.SqlSessionFactoryBean, then underlying DataSource’s auto commit mode takes effect. If DBCP based DataSource is used, “defaultAutoCommit” attribute decides auto commit mode.
To sum up, the rules are as follows.
SqlSessionFactory generator | TransactionManager | Auto commit mode |
---|---|---|
SqlSessionFactoryBuilder | JDBC | SqlSession.openSession(autoCommit) |
SqlSessionFactoryBuilder | MANAGED | Container’s policy |
SqlSessionFactoryBean | N/A | DataSource’s policy |
* SqlSessionFactoryBean is in mybatis-spring project
* Above rule is verified on mybatis 3.5.1 and mybatis-spring 2.0.1