Set Isolation Level on MyBatis

On this example, im trying to set mybatis default isolation level, but before i go further let me explain a little why we need to setup an isolation level.

In a typical application, multiple transactions run concurrently, often working with the same data to get their job done. Concurrency, while necessary, can lead to the following problems:

Dirty read—Dirty reads occur when one transaction reads data that has been written but not yet committed by another transaction. If the changes are later rolled back, the data obtained by the first transaction will be invalid.

Nonrepeatable read—Nonrepeatable reads happen when a transaction performs the same query two or more times and each time the data is different. This is usually due to another concurrent transaction updating the data between the queries.

Phantom reads—Phantom reads are similar to nonrepeatable reads. These occur when a transaction (T1) reads several rows, and then a concurrent transaction (T2) inserts rows. Upon subsequent queries, the first transaction (T1) finds additional rows that were not there before.

That’s why on some mission critical application, i always set Isolation Level on Serializable. Why i use Serializable because this fully ACID-compliant isolation level ensures that dirty reads, nonrepeatable reads, and phantom reads are all prevented. This is the slowest of all isolation levels because it is typically accomplished by doing full table locks on the tables involved in the transaction.

Okay, here is how to achieve Serializable Isolation Level using MyBatis,

import com.edw.mybatis.bean.Testing;
import com.edw.mybatis.config.MyBatisSqlSessionFactory;
import com.edw.mybatis.mapper.TestingMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.log4j.Logger;

public class Main {

    private static Logger logger = Logger.getLogger(Main.class);

    public static void main(String[] args) {

        SqlSessionFactory sqlSessionFactory = MyBatisSqlSessionFactory.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession(TransactionIsolationLevel.SERIALIZABLE);
        TestingMapper testingMapper = sqlSession.getMapper(TestingMapper.class);

        try {
            Testing testing = new Testing();
            testing.setName("name 1");
            testing.setAddress("address 1");

            int success = testingMapper.insert(testing);
            logger.debug(success);
            
            sqlSession.commit();
        } catch (Exception e) {
            logger.error(e, e);
            sqlSession.rollback();
        } finally {
            sqlSession.close();
        }
    }
}

Hope this piece of code could help others, have fun with other TransactionIsolationLevel parameters, such as READ_COMMITTED or REPEATABLE_READ. 😉

Leave a Comment

Your email address will not be published.