【转载】Springboot2.x 事务

发布时间 2023-12-16 17:41:21作者: 夏秋初

参考

环境

环境 版本 操作
windows 10
vs code 1.84.2
Spring Boot Extension Pack v0.2.1 vscode插件
Extension Pack for Java v0.25.15 vscode插件
JDK 11
Springboot 2.3.12.RELEASE
mybatis-spring-boot-starter 2.1.4 mvn依赖
Apache Maven 3.8.6

正文

注解式

内容转载自其他文章,并非从官方文档中查询得知,仅供参考。

  • @Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。因此可以在 Service 层和 Controller 层使用。
  • 虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。
  • SpringBoot1.x需要在启动类上添加 @EnableTransactionManagement ,SpringBoot2.x则不需要。
  • 在单元测试的时候,测试方法添加 @Transactional 注解后会自动回滚。

此处暂时不理解,仅作记录。

// 指定回滚
@Transactional(rollbackFor=Exception.class) 

// 指定不会滚
@Transactional(noRollbackFor=Exception.class)

// 有事务加入、没有事务则新建
@Transactional(propagation=Propagation.REQUIRED) 

// 容器不为这个方法开启事务
@Transactional(propagation=Propagation.NOT_SUPPORTED)

// 只读,不能更新删除
@Transactional (propagation = Propagation.REQUIRED,readOnly=true) 

// 超时时间
@Transactional (propagation = Propagation.REQUIRED,timeout=30)

// 数据库隔离级别
@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)
  • 在测试中使用
package com.xiaqiuchu.demo.service;

import static org.junit.jupiter.api.Assertions.assertNotEquals;

import javax.annotation.Resource;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;


@SpringBootTest
public class StudentServiceTest {

    @Resource
    StudentService studentService;
    
    @Test
    // 在测试中,开启事务会自动回滚(不在测试中的时候捕获到受查异常时,会自动回滚。)
    @Transactional
    void testUpdateNameById() {
        Integer updateNum = studentService.updateNameById(1L, "王小黑");
        assertNotEquals(updateNum, 0);
    }
}

手动事务(代码)

package com.xiaqiuchu.demo.service;

import java.util.ArrayList;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import com.xiaqiuchu.demo.entity.Student;
import com.xiaqiuchu.demo.mapper.StudentMapper;

@Service
public class StudentService {
    @Resource
    StudentMapper studentMaper;

    @Resource
    private PlatformTransactionManager platformTransactionManager;

    @Resource
    private TransactionDefinition transactionDefinition;

    public Integer updateNameById(Long id, String name){
        // 开启事务
        TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);

        Integer updateNum = studentMaper.updateNameById(id, name);

        // 提交
        platformTransactionManager.commit(transactionStatus); 
        // 回滚(这里应该放到异常处理块里面,当前仅演示)
        // platformTransactionManager.rollback(transactionStatus); 

        return updateNum;

    }
    
}