当前位置: 首页 > news >正文

JavaWeb 课堂笔记 —— 23 事务管理

本文介绍了Spring事务管理的基本概念和应用。事务是一组原子性操作,通过@Transactional注解实现。文章以解散部门为例,展示了事务的回滚机制(rollbackFor)和传播行为(propagation)。重点说明了当需要将不同操作分离为独立事务时,使用REQUIRES_NEW传播行为的重要性。通过日志记录案例,演示了如何确保关键操作不受主事务异常影响。这些机制有效解决了数据一致性问题,是Spring事务管理的核心功能。

01 事务

事务是一组操作的集合,其是一个不可分割的工作单位,这些操作要么同时成功,要么同时失败。

操作:

  • 开启事务 start transaction / begin
  • 提交事务 commit
  • 回滚事务 rollback

02 案例:解散部门

EmpMapper.java

    /*** 删除部门下属员工信息* @param deptId*/@Delete("delete from emp where dept_id = #{# deptId}")void deleteByDeptId(Integer deptId);

DeptServiceImpl.java

    @Overridepublic void delete(Integer id) {deptMapper.deleteById(id); //1、删除部门//2、删除下属员工数据empMapper.deleteByDeptId(id);}

问题:即使程序运行抛出了异常,部门依然制除了,但是部门下的员工却没有刷除,造成了数据的不一致。

方法:在DeptServiceImpl.javadelete方法当中,添加注解@Tramsactional,将删除部门和删除部门下属员工两步操作封装为事务,在事务运行前开启事务,在事务运行后提交或回滚事务。

03 Spring事务管理

注解:@Tramsactional

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

作用:将当前方法交给Spring进行事务管理,方法执行前开启事务,方法执行后提交事务,方法出现异常回滚事务。

在这里插入图片描述

注:一般将注解@Tramsactional添加在增删改查操作上

application.yml

#spring事务管理日志
logging:level:org.springframework.jdbc.support.JdbcTransactionManager: debug

在这里插入图片描述

04 rollbackfor(控制事务异常类型)

问题:我们添加主动抛出异常代码时,下面的删除部门下属员工操作并没有被执行到,即便添加了注解@Tramsactional,也并未进行事务回滚操作,为什么呢?事实上,只有出现RuntimeException才回滚异常。这里,我们提供一种新的方法,rollbackfor,其属性用于控制出现何种异常类型,回滚事务。

if(true){throw new Exception("出错啦...");
}

DeptServiceImpl.java

    @Transactional(rollbackFor = Exception.class) //spring事务管理@Overridepublic void delete(Integer id) throws Exception{deptMapper.deleteById(id); //1、删除部门//int i = 1/0;if(true){throw new Exception("出错啦~~~");}//2、删除下属员工数据empMapper.deleteByDeptId(id);}

在这里插入图片描述

05 propagation(控制事务传播行为)

事务传播行为是指指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。比如,a方法和b方法中都添加了注解@Tramsactional,说明a方法和b方法都具有事务,那么在a方法运行时调用b方法,b方法的事务时加入a方法的事务呢还是新建一个事务?

在这里插入图片描述

在这里插入图片描述

06 案例:解散部门第二弹

需求:解散部门时,不论成功还是失败,都要记录日志

步骤:解散部门时,删除部门及其下属员工,并记录日志到数据库表中

牛马开发:

DeptLog.java

package com.itheima.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDateTime;@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeptLog {private Integer id;private LocalDateTime createTime;private String description;
}

DeptLogMapper.java

package com.itheima.mapper;import com.itheima.pojo.DeptLog;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface DeptLogMapper {@Insert("insert into dept_log(create_time,description) values(#{createTime},#{description})")void insert(DeptLog log);}

DeptLogService.java

package com.itheima.service;import com.itheima.pojo.DeptLog;public interface DeptLogService {void insert(DeptLog deptLog);
}

DeptLogServiceImpl.java

package com.itheima.service.impl;import com.itheima.mapper.DeptLogMapper;
import com.itheima.pojo.DeptLog;
import com.itheima.service.DeptLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;@Service
public class DeptLogServiceImpl implements DeptLogService {@Autowiredprivate DeptLogMapper deptLogMapper;@Transactional@Overridepublic void insert(DeptLog deptLog) {deptLogMapper.insert(deptLog);}
}

表结构

create table dept_log(id int auto_increment comment '主键ID' primary key,create_time datetime null comment '操作时间',description varchar(300) null comment '操作描述'
)comment '部门操作日志表';

问题:删除部门和记录日志是同一个事务,当删除部门出现异常,记录日志也会回滚,从而导致异常无法被记录,需要将这两个事务分开,在文件DeptLogServiceImpl.java的注释@Transactional中添加默认事务控制REQUIRES_NEW,执行insert操作时会新建一个事务,不被异常干扰。

@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void insert(DeptLog deptLog) {deptLogMapper.insert(deptLog);
}

在这里插入图片描述

http://www.dtcms.com/a/418840.html

相关文章:

  • 一阶微分方程求解方法详解:构建系统学习笔记
  • display ip routing-table protocol ospf 概念及题目
  • 河北邯郸建网站大学网站建设的目标与思路
  • Python学习历程——基础语法(print打印、变量、运算)
  • 【从零开始学习RabbitMQ】
  • Kafka08-优化-尚硅谷
  • 小杰深度学习(two)——全连接与链式求导
  • vue警告:Extraneous non-props attributes (class) were passed to component
  • 记录第一次搭建ELK+filebeat环境
  • 【复习】计网每日一题--多播
  • 狮山网站开发wordpress轩小程序
  • Ubuntu22.04——配置固定IP
  • 记Bugku CTF平台解题过程
  • OceanBase主备库日志传输服务
  • React-props的children属性
  • 济宁做网站的公司邯郸公司网站建设
  • 特别分享:关于Pipeline
  • 速通ACM省铜第十七天 赋源码(Racing)
  • ARM(IMX6ULL)——通信(IIC/I2C)
  • 零基础学AI大模型之LangChain-PromptTemplate
  • FFT去除规律条纹
  • JAVA中的权限修饰符
  • 前端面试十四之webpack和vite有什么区别
  • 小米路由器 做网站银川森林半岛
  • Kafka04-知识速记
  • 【Linux】高级I/O
  • 开源的容器化平台:Docker高级应用与实战案例
  • 3.7 广域网 (答案见原书 P116)
  • 临淄网站制作首选公司seo排名需要多少钱
  • k8s-部署单master节点