【JavaWeb | 第十篇】Spring中的事务控制

目录

一、什么是事务?

二、Spring事务管理

[2.1 基本事务管理](#2.1 基本事务管理)

[2.2 事务进阶-rollbackFor](#2.2 事务进阶-rollbackFor)

[2.3 事务进阶-propagation](#2.3 事务进阶-propagation)


一、什么是事务?

关于什么是事务,在MySQL篇中的第五篇有详细的介绍。

【MySQL | 第五篇】事务控制https://blog.csdn.net/iting_0924/article/details/160546488?spm=1001.2014.3001.5501

如果没有事务会发生什么?

在我们添加员工信息时,我们需要操作两张数据库表------Emp表和EmpExpr表,并且EmpExpr表中的dept_id是根据Emp表中的id录入的,如果在操作完Emp表之后服务器出现错误,那么后面的员工工作经历信息就无法录入,会出现数据库保存数据不完整、不一致的问题,这显然是不符合业务逻辑的。因此我们需要引入事务,将这两个操作设置为一个事务,整体进行操作。

首先,新增员工的Service层的业务代码实现:

java 复制代码
    @Override
    public void save(Emp emp) {
        //1.保存员工基本信息
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.insert(emp);

        //2.批量保存员工工作经历信息
        List<EmpExpr> exprList = emp.getExprList();
        if(!CollectionUtils.isEmpty(exprList)){
            exprList.forEach(empExpr ->{
                empExpr.setEmpId(emp.getId());
            });
            empExprMapper.insertBatch(exprList);
        }

我们要将这两步操作封装到一个事务当中,保证数据库操作的一致性。Spring提供了事务的封装,Spring事务管理

二、Spring事务管理

2.1 基本事务管理

注解@Transactional

作用:将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务

位置:业务(service)层的方法上、类上、接口上。

注:推荐将该注解添加到业务层指定的方法上。

我们在save方法上添加上**@Transactional**注解:

java 复制代码
    @Transactional
    @Override
    public void save(Emp emp) {
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.insert(emp);

        List<EmpExpr> exprList = emp.getExprList();
        if(!CollectionUtils.isEmpty(exprList)){
            exprList.forEach(empExpr ->{
                empExpr.setEmpId(emp.getId());
            });
            empExprMapper.insertBatch(exprList);
        }

添加注解之后在运行时就会出现,初始化事务的debug信息。如果中间出错,那么事务就会rollback到之前的状态。

2.2 事务进阶-rollbackFor

rollbackFor属性用于控制出现何种异常类型,回滚事务。

例如:

java 复制代码
@Transactional(rollbackFor = {Exception.class})

代表出现所有的异常都要进行事务的回滚。

注意:默认出现运行时异常RuntimeException才会回滚。

2.3 事务进阶-propagation

事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。

例如:方法a和方法b都声明了是一个事务,而且方法a中间还调用了b方法,那么b方法应该加入当前的事务,还是应该再新建一个事务呢?

假如b方法是用来插入数据操作日志信息的,这个b方法无论a方法执行成功与否,b都要执行一次,因此需要给这个方法添加一个propagation = Propagation.REQUIRED属性。

属性值:

相关推荐
葫芦和十三几秒前
图解 MongoDB 09|explain 再读:从 queryPlanner 到 executionStats
后端·mongodb·agent
葫芦和十三7 分钟前
图解 MongoDB 10|覆盖查询:让索引把活干完,根本不用回表
后端·mongodb·agent
大鸡腿同学2 小时前
从 CoT 思维链到 ReAct:智能 Agent 到底是怎么 “思考” 的?
后端
IT_陈寒3 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
小bo波4 小时前
使用Thread子类创建线程 VS 使用Runnable接口创建线程的区别
java·多线程·thread·并发编程·runnable
SamDeepThinking4 小时前
高并发场景下,CompletableFuture与ForkJoinPool该如何取舍?
java·后端·面试
Asize5 小时前
多模态生图:从 Vite 工程化到前端调用 Qwen Image
javascript·人工智能·后端
java小白小5 小时前
SpringBoot(09):缓存实战——穿透、雪崩、击穿的解决方案
后端
java小白小5 小时前
SpringBoot(08):Redis 集成——5 分钟给你的项目加上缓存
后端
LiuMingXin5 小时前
意图与代码之间:AI编程范式全景解读
前端·后端·面试