开发中易犯错的事务问题

1.不指定rollbackFor

使用spring的声明式事务(即@Transactional注解)时,如果不指定rollbackFor,那么当程序发生Error时,事务将不会回滚!!!显然这将导致数据不一致!
如下述代码:

	@Transactionalpublic void createXxx(final XxxCreateDTO dto) {// 其它处理......xxxRepository.insertList(this.assembleItemList(dto));}

spring官方解释如下:
在这里插入图片描述

2.捕获异常后,没有继续传递异常

如果事务方法捕获了异常,但是没有在catch块中继续抛出异常,那么该事务将不会回滚!!显然这将导致数据不一致!

	@Transactional(rollbackFor = Exception.class)public ResultDTO apply(XxxApplyModel applyModel) {try {return internalApply(applyModel);} catch (Exception e) {// 捕获异常后的一些处理,但是却没有继续抛出异常......}}}

正确的做法有两种:

  1. 在catch中抛出异常
	@Transactional(rollbackFor = Exception.class)public ResultDTO apply(XxxApplyModel applyModel) {try {return internalApply(applyModel);} catch (Exception e) {// 捕获异常后的一些处理,但是却没有继续抛出异常......throw e;}}
  1. 将事务的开启下沉到内部逻辑中,如本例中可以将事务的开启放到方法internalApply
    public ResultDTO apply(XxxApplyModel applyModel) {try {// 注意,要通过bean调用这个方法internalApply,不能通过this,// 方法内部的调用不会开启事务return internalApply(applyModel);} catch (Exception e) {// 捕获异常后的一些处理,但是却没有继续抛出异常......}}@Transactional(rollbackFor = Exception.class)public FooDTO internalApply(XxxApplyModel applyModel) {// business process......}

3.大事务问题

大事务,简单的说就是在一个事务中处理了很多其它耗时的操作,比如在事务中发起多个远程调用,耗时的校验逻辑放在了事务方法中等等,这会导致该事务的connection不能尽快释放,占用数据库资源,降低系统性能,如下面的方法:

@Transactional(rollbackFor = Exception.class)
public ResultDTO apply(ApplyDTO applyDTO) {try {// 条件校验this.validateApply(applyDTO);} catch (Exception e) {return getApplyResultOnException(e, productNo);}// 业务处理 保存数据等操作......return buildApplyResult(productNo, null, null, true);}

上述事务方法中校验逻辑validateApply是很耗时的,但是却放在了事务方法中,显然不合理。建议新加一个方法,依次调用apply方法和validateApply方法

public Foo applyXxx(ApplyDTO applyDTO) {this.validateApply(applyDTO);return apply(uniqueKey, applyDTO) }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/15067.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划--Fibonacci数列 III

描述 众所周知,Fibonacci数列是一个著名数列。它的定义是: 本题要求采用第三种方法:简单的动态规划。 用数组把求出来的 Fibonacci 数列保存下来,以免后面要的时候再算一次。 输入描述 每行一个整数 i ,表示 Fibona…

Linux C程序开发,多线程编程、网络编程

目录 多线程编程 网络编程 Linux C程序开发是指在Linux操作系统下使用C语言进行开发的过程。Linux是一种开源的操作系统,具有稳定性、安全性和灵活性等优点,因此在很多领域都得到了广泛的应用。 多线程编程 多线程编程是指在一个程序中同时运行多个线…

Neo4J 特性CQL语句,函数,Springboot集成

Neo4J Neo4J Neo4J一、Neo4J相关介绍1.为什么需要图数据库方案1:Google方案2:Facebook 2.特性和优势3.什么是Neo4j4.Neo4j数据模型图论基础属性图模型Neo4j的构建元素 5.软件安装 二、CQL语句1.CQL简介2.CREATE 命令3.MATCH 命令4.RETURN 子句5.MATCH和R…

Spark—通过Java、Scala API实现WordCount案例的基本操作

实验原理 Spark的核心就是RDD,所有在RDD上的操作会被运行在Cluster上,Driver程序启动很多Workers,Workers在(分布式)文件系统中读取数据后转化为RDD(弹性分布式数据集),然后对RDD在…

FreeRTOS ~(七)互斥量 ~ (1/3)互斥量解决互斥缺陷

前情提要 FreeRTOS ~(四)同步互斥与通信 ~ (2/3)互斥的缺陷 FreeRTOS ~(五)队列的常规使用 ~ (2/5)队列解决互斥缺陷 FreeRTOS ~(六)信号量 ~ (2/…

文字磨练课程:提高编辑和校对效率的方法

提高编辑和校对效率,可以使你更有效地完成写作任务,提升文章质量。以下是一些方法,可以帮助你在编辑和校对过程中提高效率。 1.设定目标和计划 在开始编辑和校对前,设定明确的目标和计划。这可以帮助你集中注意力,提…

瑞芯微:基于RKNN3568得ufldv2部署

Lane检测是自动驾驶和高级驾驶员辅助系统(ADAS)的基本组成部分,用于区分和定位道路上的车道线。尽管深度学习模型已经取得了巨大成功,但仍有一些重要且具有挑战性的问题需要解决。 第一个问题是效率问题。在实践中,车…

从JDK源码级别剖析JVM类加载机制

1 什么是Java虚拟机 一个可执行java字节码的虚拟机进程;跨平台的是java程序,而不是java虚拟机,java虚拟机在各个操作系统是不兼容的,例如windows、linux、mac都需要安装各自版本的虚拟机,java虚拟机通过jdk实现功能。…

docker-compose实现微服务jar+mysql的容器服务发布(经典版)

一 安装mysql服务 1.1 拉取镜像 1.拉取: docker pull mysql:5.7.29 2.查看镜像: docker images 1.2 在宿主机创建文件存储mysql 1.创建映射目录:mysql-c5 在/root/export/dockertest 目录下,mkdir -p mysql-c5 &#…

Elasticsearch介绍和安装

ELK简介 Elastic Stack核心产品包括Elasticsearch、Logstash、Kibana(也称为ELK)和Beats等等。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化 Kibana是一个免费且开放的用户界面,能…

LVS +Keepalived高可用群集

文章目录 一、Keepalived概述二、Keepalived服务重要功能1.管理 LVS 负载均衡软件2.支持故障自动切换(Failover)3.实现 LVS 集群中节点的健康检查(Health Checking)4.VRRP通信原理 三、keepalived体系主要模块及作用四、keepalive…

LogicFlow 在HTML中的引入与使用

LogicFlow 在HTML中的引入与使用 LogicFlow的引入与使用,相较于BPMNJS相对容易一些,更加灵活一些,但是扩展代码可能写得更多一些。 示例展示 示例代码 github: https://github.com/iotzzh/origin-examples/blob/main/%E6%B5%81%E7%A8%8B%E5%9…