Springboot 之 事务支持

本文通过一个小实验展示了在SpringBoot应用中,当出现异常时,未启用事务管理会导致数据不一致的问题。SpringBoot提供了@Transactional注解来支持事务管理,确保原子性,避免数据混乱。在代码示例中,添加@Transactional后,当异常发生时,数据库中的数据将不会被更新,保持了事务的完整性。实验强调了事务管理在维护数据库状态方面的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.2 Spring Boot 事务支持

一般事务只跟DML语句有关系,并且事务的编写一般写在业务层(service)

3.2.1小实验

在开始学习了解Springboot支持之前,我们先做一个小实验,就拿之前通过Mybaties逆向工程生成的项目做即可

在控制层编写StudentController类,代码如下:

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @RequestMapping(value = "/update")
    public Object update(Integer id, String studentName) {
        Student student = new Student();
        student.setId(id);
        student.setStuName(studentName);
        int modefyCount = studentService.modifyStudentById(student);
        return "修改的结果:" + modefyCount;
    }

    @RequestMapping(value = "/student/details")
    public Object studentDetail(Integer id){
        Student student = studentService.queryStudentById(id);
        return student;
    }
}

上面代码提供两个接口,update表示接收前端传来的id以及studentName,实例化一个Student对象,根据该对象改变对应id的name值,student/details表示根据id查看对应学生的信息

在业务层编写接口:

public interface StudentService {

    /*
    * 根据学生id获取学生详情
    * */

    Student queryStudentById(Integer id);

    /**
     * 根据student对象更新学生信息
     * @param student
     * @return
     */
    int modifyStudentById(Student student);
}

对应实现类:

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public Student queryStudentById(Integer id) {
        return studentMapper.selectByPrimaryKey(id);
    }

    @Override
    public int modifyStudentById(Student student){
        int modefyCount = studentMapper.updateByPrimaryKeySelective(student);
        
        int a = 10/0;
        
        return modefyCount;
    }
}

实现类通过调用逆向工程生成的方法去对数据库进行操作

如果一位开发者稍有细心,会发现modifyStudentById方法中有一处异常: int a = 10/0,当代码运行到这一句时,java会抛出这个错误:java.lang.ArithmeticException: / by zero 。这就引出了下面的问题:

当我们进行某项事务到一半,却因为某些异常或其他原因意外导致事务没有完整地完成,这个时候,如果我们仍然默许事务执行前半部分,这无疑就破坏了事务的原子性,同时也会产生数据层面的混乱,明明不该改变的数据却改变了,这是不应该被我们允许的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYOB0jVg-1623048692638)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210607132632377.png)]

此时出现了错误页面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wTJOYfuc-1623048692639)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210607132653298.png)]
但是数据依然被修改了:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PmGp1qOu-1623048692640)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210607132715710.png)]

可以看到虽然后端报出了错误,但是却依旧执行了数据的update操作。

3.2.2 Springboot的事务支持

Springboot提供了事务支持,保证事务具有原子性,其底层依然采用的是 Spring 本身提供的事务管理

在业务层的实现类方法上添加注解 @Transactional

我们为service层的实现类代码添加注解:

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Transactional
    @Override
    public Student queryStudentById(Integer id) {
        return studentMapper.selectByPrimaryKey(id);
    }

    @Transactional
    @Override
    public int modifyStudentById(Student student){

        int modefyCount = studentMapper.updateByPrimaryKeySelective(student);

        int a = 10/0;

        return modefyCount;
    }
}
编译测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IcI68Lqe-1623048692641)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210607144059794.png)]

可以看到报错了:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B9LKd7yR-1623048692642)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210607144117602.png)]

但是数据库的数据并没有改变:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NxfeaVa5-1623048692642)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210607144059794.png)]

入口类中的 @EnableTransactionManagement

在有些项目的后端我们还会看到在注解类里面加上了这么一个注解:@EnableTransactionManagement

@SpringBootApplication
@EnableTransactionManagement
public class SpringbootWorkspaceApplication {

   public static void main(String[] args) {
      SpringApplication.run(SpringbootWorkspaceApplication.class, args);
   }

}

该注解属于可选项,事实上Springboot对于事务的支持依靠@Transactional注解来实现,所以只需要使用@Transactional注解就可。

下一篇博客:
Springboot中的MVC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值