Open
Description
the Using the MyBatis API doc says:
- It will not participate in any Spring transactions.
- If the SqlSession is using a DataSource that is also being used by a Spring transaction manager and there is currently a transaction in progress, this code will throw an exception.
but my test produces different result:
- using api does participate in Spring transactions
- not throw exception
below is the test code, use mybatis-spring-boot-starter:2.1.3, keep the default auto configuration, the table is simple
when the exception throws, all inserts roll back
does the doc wrong? or I misunderstand something?
package com.example.demo;
import java.util.Arrays;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class TransactionTest implements ApplicationRunner {
/**
* auto configure one
*/
@Autowired
private SqlSessionFactory SqlSessionFactory;
/**
* auto configure one
*/
@Autowired
private PersonMapper personMapper;
@Override
@Transactional
public void run(ApplicationArguments args) throws Exception {
personMapper.insertPerson("mike", 18);
try(SqlSession sqlSession = SqlSessionFactory.openSession(ExecutorType.BATCH)) {
List<String> dogNames = Arrays.asList("aaa", "bbb");
DogMapper dogMapper = sqlSession.getMapper(DogMapper.class);
for (String name: dogNames) {
dogMapper.insertDog(name);
}
sqlSession.commit();
}
if (true) {
throw new RuntimeException();
}
}
@Mapper
public interface PersonMapper {
@Insert("insert into person(name, age) values(#{name}, #{age})")
void insertPerson(@Param("name") String name, @Param("age") int age);
}
@Mapper
public interface DogMapper {
@Insert("insert into dog(name) values(#{name})")
void insertDog(String name);
}
}