MySQL实现SQL Server中UPDLOCK与READPAST组合功能

        碰到一位同事求助解决消息中台一个线上的bug,具体描述如下:

        首先有一张主表记录消息待发送的内容,一张子表记录本条消息的发送状态。若发送成功则将此条消息的发送状态修改为已发送并做逻辑删除。代码通过定时任务每2s轮询子表,如果状态是未发送且没有被删除的记录,则进行发送。发送前代码会对当前消息更新加入UPDLOCK与READPAST,期望下一次轮询时能够自动跳过被锁(发送中)的数据,发送完成后更新状态提交事务,行锁自动释放。

        现在碰到的问题是子表整张表发生死锁,导致消息无法发送。经过代码review,也无法找到互相持有资源的情况,并且即便行锁一直没有释放,也不会影响新生成的消息发送。一开始以为是消息渠道的问题,但是在重启数据库后,bug消失了,所以还是认为由死锁引起的问题。

        机缘巧合下发现有这样一个说法,Sql Server会自动升级锁,这是一个比较玄学的问题,因为对Sql Server用的不是很多,不甚了解。不过这也好解释,发生死锁的原因:

       在sendFeishuMsgJob方法中,对数据表上锁,extracted方法中,需要等待表锁释放才能更新,然而数据表的锁需要extracted执行完才能释放,因此造成了死锁。

       虽然不知道这个解释对不对,但是想到一个问题,如果数据库换成比较常用的MySQL如何实现Sql Server中UPDLOCK与READPAST组合功能。

        首先从事务的隔离级别考虑,MySQL的事务隔离级别分为4种:

  1. READ UNCOMMITTED(读未提交)事务A会读到事务B还未提交的数据
  2. READ COMMITTED(读已提交)事务A不会读到事务B还未提交的数据
  3. REPEATABLE READ (可重复读)(默认隔离级别)事务开启时读到的数据,在事务提交前,是一致的,不会因为外面事务的修改提交而改变开启事务前读到的值
  4. SERIALIZABLE(可串行化)严格按照串行序列排队执行事务,一个事务A执行提交结束以后,事务B才会开启

        由此可见,仅通过事务隔离想要达到UPDLOCK和READPAST的效果,需要使用第4种事务隔离级别——串行化。其他3种隔离级别不管修改是否提交,都能读到数据,就很有可能造成消息的重复发送。但是从串行化的描述可知,所有的事务都是排队执行,如果在执行过程中业务处理速度慢,就会造成其他事务等待的情况,成为性能瓶颈。

        好在MySQL 8.0.22 及更高版本中提供了SELECT ... FOR UPDATE SKIP LOCKED方法,可以支持REPEATABLE READ事务隔离级别中,跳过添加行锁的数据行读取。

        示例如下:

事务A

START TRANSACTION;
SELECT * FROM lock_test.for_update_test_2 WHERE id = 1 FOR UPDATE;
SELECT SLEEP(15); 
COMMIT;

事务B

START TRANSACTION;
SELECT * FROM lock_test.for_update_test_2 FOR UPDATE SKIP LOCKED;
COMMIT;

运行结果

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

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

相关文章

安装cuda支持的opencv-python Windows版本(包含常见错误处理)

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G技术研究。 博客内容主要围绕…

节点使用简介:comfyui-photoshop

1、安装comfyui-photoshop 略过 一点要注意的是:在Photoshop上的安装增效工具,要通过Creative Cloud 桌面应用程序进行安装,才能成功在增效工具中显示,直接通过将文件解压到Plug-ins路径行不通(至少对我来说行不通&am…

C++语言基础|函数的嵌套与递归

C语言基础|函数的嵌套与递归 1. 函数的嵌套调用2. 函数的递归调用 1. 函数的嵌套调用 在一个函数中调用其它函数叫函数的嵌套。C中函数的定义是平行的,除了main()以外,都可以互相调用。函数不可以嵌套定义,但可以嵌套调用。比如函数1调用了函…

【百度】25届秋招内推码

内推码 IV1RBB 介绍 📣 百度TPG技术中台事业群组—深度学习技术平台部 25届校招正在进行中,可通过定向内推形式get校招绿色通道 ! 欢迎联系我定向内推 🌟【部门介绍】 飞桨(PaddlePaddle)以百度多年的深度…

前端技巧——复杂表格在html当中的实现

应用场景 有时候我们的表格比较复杂,表头可能到处割裂,我们还需要写代码去完成这个样式,所以学会在原生html处理复杂的表格还是比较重要的。 下面我们来看这一张图: 我们可以看到有些表头项的规格不太一样,有1*1 2*…

阶段练习——minishell

目录 (一)文件复制(my_cp函数) (二)文件内容查看(my_cat函数) (三)切换目录(my_cd函数) (四)列出目录内容…

Elasticsearch、Easy-es 快速入门 SearchAfterPage分页 若依前后端分离 Ruoyi-Vue SpringBoot

一、环境安装 Elasticsearch ik分词器 1.1 下载解压Elasticsearch-7.x版本,越高越好,低版本有Log4j漏洞,Easy-es目前支持7.x 1.2 IK中文分词器 将对应Elasticsearch版本IK放进文件夹,Elasticsearch-7.6.1,ik对应版…

Postgres 超时 (Timeout) 详解

原文地址 https://www.bytebase.com/blog/postgres-timeout/ PostgreSQL 提供各种超时 (Timeout) 设置,通过控制某些进程的持续时间来帮助管理和优化数据库操作。这些超时对于确保系统的稳定性和性能至关重要,尤其是在高流量或复杂查询的环境中。让我们…

STM32CubeMX生成stm32MP135中断优先级配置错误修正方法

0 修改方法 使用STM32CubeMX生成stm32MP135代码的中断优先级配置错误,将导致所有中断优先级设置不对。 如果设置EXTI0中断优先级为10,在STM32CubeMX中配置如下: 生成的中断优先级配置代码为: 正确写法应该将中断优先级左移3位&…

python从入门到精通:函数

目录 1、函数介绍 2、函数的定义 3、函数的传入参数 4、函数的返回值 5、函数说明文档 6、函数的嵌套调用 7、变量的作用域 1、函数介绍 函数是组织好的,可重复使用的,用来实现特定功能的代码段。 name "zhangsan"; length len(nam…

二叉树学习笔记

一、树的概念 树是一种非线性的结构,它是由n个有限结点组成的一个具层次关系的集合。(像一颗倒着的树) 特点: 有一个特殊的结点,称之为根结点,根结点没有前驱结点 除了根节点以外,其余节点别分…

centos 7.9 迁移到 openEuler22.03-LTS-SP3

openEuler移植案例 | 移植操作指南 | openEuler社区官网 cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) 需要两台机器, 不通过原因 在待升级节点检查是否有安装x2openEuler-core时, 发现已经安装了,不能作为升级节点。该节点为: 解…

MySQL中处理JSON数据

​ 大家好,我是程序员小羊! 前言 在大数据时代,处理和分析结构化与非结构化数据的能力对于企业的成功至关重要。MySQL作为一种广泛使用的关系型数据库管理系统(RDBMS),在应对传统结构化数据方面表现出色。然…

c++每日练习记录第1天

笔记: C 中,isalnum 函数用于检查一个字符是否是字母数字字符,isalnum 函数定义在 头文件中。双指针法,双指针法是一种常用的算法技巧,特别适用于处理数组、字符串等线性数据结构中的问题。这种方法通常涉及到两个指针…

12、springboot3 vue3开发平台-前端-记住我功能实现

文章目录 1. 前端用户信息保存2. 登录页面添加3. 后端实现 1. 前端用户信息保存 使用pinia持久化保存用户名密码 src/stores/remember-me.js // 定义 store import { defineStore } from "pinia" import {reactive} from vueexport const useRememberMeStore defi…

图书管理管理系统 (GUI)

目录 Java程序设计课程设计 图书管理管理系统 一、前言 1 研究背景 2 目的和意义 3编程环境与工具 二、图书管理系统概述 1主要业务流程 三、需求分析与设计 1 系统需求分析 2.功能需求 3.性能需求 4. 安全需求 2 数据库设计 3 界面设计 四、 总…

Solidworks二次开发:通过XYZ点的曲线

在SolidWorks中,通过XYZ点创建曲线是一种根据一组点的坐标生成三维曲线的方法。这种方法适用于需要根据特定点集设计曲线的情况,比如在建模复杂几何形状或执行逆向工程时。在SolidWorks中通过XYZ点创建曲线,操作步骤如下 打开SolidWorks并新建…

利用modelscope下载模型

1. modelscope的简介 ModelScope作为一个先进的“模型即服务”(MaaS)平台,它的核心在于汇聚人工智能领域的尖端模型,降低了在现实世界应用这些前沿技术的门槛。该平台通过ModelScope库展现了其强大功能,这一库专为简化开发者体验而设计&…

Element-06.案例

一.目标 实现下面这个页面,表格中的数据使用axois异步加载数据 二.实现步骤 首先在vue项目的views文件夹中新建一个tlias文件夹,用来存储该案例的相关组件。员工页面组件(EmpView.vue)和部门页面组件(DeptView.vue&…

C语言指针详解-上

C语言指针详解-上 前言1.指针的基本概念1.1指针是什么1.2指针的声明与初始化1.3取地址符&和解引用符*& 运算符用于**获取变量的地址*** 运算符用于访问指针指向的值 2.指针的类型常见数据类型的指针指针与数组、字符串数组指针结构体指针函数指针二级指针void指针 3.指…