Spring 事务方法调用问题(@Transactional)

前置条件

创建表

CREATE TABLE `test_table` (
  `id` int(9) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(10) CHARACTER SET latin1 DEFAULT NULL COMMENT '姓名',
  `sex` tinyint(1) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

实体类

/**
 * 缺少package
 */
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("test_table")
public class TestTable {
    
    private Integer id;

    private String name;

    private Byte sex;

    public TestTable() {
    }


    public TestTable(Integer id, String name, Byte sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }
}

测试类

import edu.haut.springboottest.service.TestTableService;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
class SpringbootTestApplicationTests {

    @Resource
    private TestTableService testTableService;

    @Test
    void contextLoads() {
        testTableService.add();
    }

}

事务方法调用非事务方法(相同类下)

import edu.haut.springboottest.entity.TestTable;
import edu.haut.springboottest.mapper.TestTableMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class TestTableService {

    @Resource
    private TestTableMapper testTableMapper;

    @Transactional
    public void add() {
        add1();
        add2();
        add3();
    }

//    @Transactional
    public void add1() {
        testTableMapper.selectById(1);
    }

//    @Transactional
    public void add2() {
        add4();
    }

    @Transactional
    public void add3() {
        testTableMapper.insert(new TestTable(1, "ceshi", (byte) 1));
    }

//    @Transactional
    public void add4() {
        testTableMapper.insert(new TestTable(1, "ceshi", (byte) 1));
        testTableMapper.insert(new TestTable(1, "ceshi", (byte) 1));
    }
}

结果:没有插入成功,事务生效

非事务方法使用事务方法(同类内)

import edu.haut.springboottest.entity.TestTable;
import edu.haut.springboottest.mapper.TestTableMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class TestTableService {

    @Resource
    private TestTableMapper testTableMapper;

//    @Transactional
    public void add() {
        add1();
        add2();
        add3();
    }

    @Transactional
    public void add1() {
        testTableMapper.selectById(1);
    }

    @Transactional
    public void add2() {
        add4();
    }

    @Transactional
    public void add3() {
        testTableMapper.insert(new TestTable(1, "ceshi", (byte) 1));
    }

    @Transactional
    public void add4() {
        testTableMapper.insert(new TestTable(1, "ceshi", (byte) 1));
        testTableMapper.insert(new TestTable(1, "ceshi", (byte) 1));
    }
}

不论多深层的方法,都插入了一条数据。事务控制失败

同类内,非事务方法调用事务方法

我们往往把查询操作与某些需要控制事务的逻辑进行分析,同类内调用事务方法时,使用的并不是spring容器管理的对象,所以失效。(没有看具体源码)

解决方案:我们把方法抽离,通过spring容器引入对象,调用方法

你可能感兴趣的:(spring)