mybatis / spring

Spring integration for MyBatis 3
Apache License 2.0
2.83k stars 2.6k forks source link

using mybatis api participate in spring transaction #531

Open linweichao opened 4 years ago

linweichao commented 4 years ago

the Using the MyBatis API doc says:

but my test produces different result:

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);
    }

}
kazuki43zoo commented 3 years ago

@linweichao

Thanks you for your reporting! I'll investigate this. I have one question. Does the current behavior cause some problems with your application ?

linweichao commented 3 years ago

It does not cause problem. This behavior is what I need.

kazuki43zoo commented 1 year ago

Should fix documentation!