排查生产环境:MySQLTransactionRollbackException数据库死锁
一. 问题现状
程序直接宕机,并在error.log日志中发现大量的报错日志,如下:
### Error updating database.
Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException:
Lock wait timeout exceeded; try restarting transaction
### The error may exist in com/xxx/dao/mapper/xxxMapper.java (best guess)
### The error may involve com.xxx.dao.mapper.xxxMapper.update-Inline
### SQL: UPDATE xxx_table SET a1=?, a2=?, a3=?, a4=?, a5=? WHERE (q1= ?)
程序中使用的是mybatis-plus,报错信息准确提示出了对应的mapper文件以及对应的sql操作是updateById语句。再结合其他日志信息,初步判断出了对应的位置以及症结可能与事务操作有关。
二. 可能原因
事务过程中执行其他非数据库操作,导致事务长期未被处理
事务未被正常处理
网段导致应用端请求未被正常发送给数据库,数据库等待应用后续操作
应用服务器性能问题,CPU爆满等导致应用无法及时切换到该进程进行处理
根据以上原因,首先排查服务器情况发现不存在cpu爆满的情况,后续继续追究MySQL事务方面的问题。
从MySQL入手,执行以下语句查看锁情况:
-- 查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
-- 查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
(由于笔者的线上环境执行了重启,所以这会儿已经看不到具体结果了,实际上应该能看到对应等待锁的事务)
但是可以模拟线上情况,比如在代码中的@Transaction代码中打个debug断点,然后观察情况:
-- 查看执行进程
SHOW PROCESSLIST;
-- 执行查询未提交事务语句
SELECT * from information_schema.INNODB_TRX;
基本可以确定问题出现在代码层。
三. 排查代码
生产伪代码如下:
@Transactional(rollbackFor = Exception.class)
public synchronized boolean doSomething(Object o){// ...if(flag){aMapper.updateById(o);}// ...bMapper.insert(o);return true;}
这里的目的是做一个事务,aMapper需要根据某个条件判断更新操作,bMapper则需要根据业务流程做新增操作,同时为了考虑并发情况下的操作所以在方法名上加了synchronized 同步锁。咋一看感觉没什么问题,但是在service层的方法上同时使用事务和锁无法保证同步。
原理是:@Transactional是使用了Sping AOP 实现的;Synchronized只是锁当前代码块,当执行完Synchronized包含的代码块就已经执行完了;此时@Transactional还未提交,所以就造成上一个事务没有提交,而下一个请求过来了争夺数据库的事务锁,在大量请求的情况下,有可能会承受不住。
针对这种情况,我们得保证让Synchronized的锁范围比@Transactional作用范围大,于是可以做如下改造:
public synchronized boolean doSomething(Object o){return transactionDoSomething(o)
}@Transactional(rollbackFor = Exception.class)
public boolean transactionDoSomething(Object o){// ...if(flag){aMapper.updateById(o);}// ...bMapper.insert(o);
}
另外一种方案:
@Transactional(rollbackFor = Exception.class)
public boolean transactionDoSomething(Object o){synchronized(this){// doSomethingreturn true;}
}
三. 扩展(ReentrantLock/druid自动重连数据库)
3.1 根因分析
经过以上处理,实际上应该不会再出现数据库死锁的情况了,但是经过日志的进一步查看发现没有将@Transaction与synchronized一起使用的地方也出现过死锁情况,在此处仅仅使用了synchronized同步锁,唯一与以上情况相似的就是同样使用了updateById。
public synchronized void doSomething(Object o){// ...xxxMapper.updateById(o);
}
剩下就是还有一种可能,网络波动、防火墙或是其他原因,导致了应用和mysql的连接断开,这个时候进入到这个代码块的执行逻辑在使用已经失败的连接,又由于这是加了synchronized的同步代码块,第一个进来的请求一直在等待连接导致后续进来的请求全都被堵塞。
3.2 改造synchronized使用ReentrantLock
于是我们在此处尽量引入一种比较友好的锁,ReentrantLock。
ReentrantLock的tryLock方法支持配置最大同步等待时间,由此来避免以上堵塞情况,写法如下:
@Service
public class LockService{// 初始化ReentrantLockprivate final Lock reentrantLock = new ReentrantLock();// 设置最大锁等待时间private final long tryLockTime = 2L;public void addRound(Long manMachineId,LocalDateTime time) {try {if (reentrantLock.tryLock(tryLockTime, TimeUnit.SECONDS)) {System.out.println("获取到锁,开始做一些事...");}else {System.out.println("等待2s后获取锁失败");}} catch (InterruptedException e) {e.printStackTrace();} finally {// 最终需要释放锁reentrantLock.unlock();}}
}
3.3 加入druid自动重连数据库
程序中使用了druid,所以我们加入以下配置信息即可实现在数据库停止的时候等待数据库恢复并自动重连,配置如下:
# 标记当Statement或连接被泄露时是否打印程序的stack traces日志
spring.datasource.druid.log-abandoned=true
# 是否自动回收超时连接
spring.datasource.druid.remove-abandoned=true
# 超时时间(以秒数为单位)
spring.datasource.druid.remove-abandoned-timeout=10
四. 总结
至此,本次MySQL线上死锁问题就已结束排查。
由于线上问题一般都比较复杂或者比较难复现,所以排查线上问题首先需要分析日志,这个时候就要求我们程序的日志要尽可能做到完善。
然后就是大胆猜测,小心验证,其中不免会经历多次推到重来的历程。此后该问题再次出现就不会再成为你的问题。
相关文章:
排查生产环境:MySQLTransactionRollbackException数据库死锁
一. 问题现状 程序直接宕机,并在error.log日志中发现大量的报错日志,如下: ### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting trans…...
140.【鸿蒙OS开发-01】
鸿蒙开发 (一)、初识鸿蒙1.初识鸿蒙(1).移动通讯技术的发展(2).完整的鸿蒙开发 (二)、鸿蒙系统介绍1.鸿蒙系统的官方定义(1).鸿蒙操作系统概述(2).鸿蒙的生态 2.鸿蒙系统的特点3.鸿蒙和安卓的对比4.鸿蒙开发的发展前景 (三)、鸿蒙开发准备工作1.鸿蒙OS的完整开发流程2.注册并实…...
npm install 下载不下来依赖解决方案
背景 最近在构建 前端自动化部署 的方案中发现了一个问题,就是我在npm install的时候,有时候成功,有时候不成功,而且什么代码也没发生更改,报错也就是那么几个错,所以在此也整理了一下遇到这种情况…...
接口自动化中cookies的处理技术
一,理论知识 为什么有cookie和session? 因为http协议是一种无状态的协议,即每次服务端接受到客户端的请求时都时一个全新的请求,服务器并不知道客户端的请求记录,session和cookie主要目的就是弥补http的无状态特性 …...
PHP 安装
您需要做什么? 为了开始使用 PHP,您可以: 找一个支持 PHP 和 MySQL 的 Web 主机在您自己的 PC 机上安装 Web 服务器,然后安装 PHP 和 MySQL 使用支持 PHP 的 Web 主机 如果您的服务器支持 PHP,那么您不需要做任何事情…...
小程序常见操作
测试时访问本地http服务器调用报错 微信开发者工具(右上角)-> 详情->本地设置->不校验合法域名、web-view(业务域名)... -> 去除勾选使用npm包 1) 工程目录下创建package.jsonnpm init(手动完成设定) / npm init -y (默认设定) 2) 安装 np…...
STM32F4串口USART发送为00的解决方案
检查接线是否正确检查TX是否为复用推挽输出 3.检查是否将TX和RX引脚重映射为USART功能 在STM32中,每个GPIO引脚可以配置为不同的复用功能,例如UART、SPI、I2C等。具体来说,GPIO_PinAFConfig函数用于配置GPIO引脚的复用功能。它的参数包括GPIO…...
重磅解读 | 阿里云 云网络领域关键技术创新
云布道师 10 月 31 日,杭州云栖大会,阿里云技术主论坛带来了一场关于阿里云主力产品与技术创新的深度解读,阿里云网络产品线负责人祝顺民带来《云智创新,网络随行》的主题发言,针对阿里云飞天洛神云网络(下…...
【蓝桥杯省赛真题45】Scratch九宫格游戏 蓝桥杯scratch图形化编程 中小学生蓝桥杯省赛真题讲解
目录 scratch九宫格游戏 一、题目要求 编程实现 二、案例分析 1、角色分析...
物联网AI MicroPython学习之语法 ADC数模模块
学物联网,来万物简单IoT物联网!! ADC 介绍 模块功能: ADC数模转换模块 ADC功能在ESP32引脚32-39上可用,使用默认配置时,ADC引脚上的输入电压必须介于0.0v和1.0v之间(任何高于1.0v的值都将读为4095&#x…...
详解Python中哈希表的使用。站在开发者角度,与大家一起探究哈希的世界。
文章目录 1. 前言2. 哈希表2.1 哈希函数2.2 哈希算法2.3 常见哈希算法2.4 哈希冲突 3.总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面…...
详解python淘宝秒杀抢购脚本程序实现
文章目录 前言一、官网下载火狐浏览器二、下载geckodriver,并解压到火狐浏览器文件夹根目录三、添加火狐浏览器根目录到系统环境变量四、下载并安装python及pycharm开发工具五、进入淘宝六、使用Pycharm运行脚本,新建python文件,将代码复制到…...
使用ChatGPT创建Makefile构建系统:使用Make运行Docker
使用ChatGPT创建Makefile构建系统:使用Make运行Docker 芯语芯愿(知乎/纷传/CSDN/);小石头的芯语芯愿(微信公众号) 开发高效现代的构建系统对于满足开发周期需求至关重要。原先,嵌入式开发者一…...
算法设计与分析复习--分支界限法
文章目录 上一篇分支界限法性质装载问题0-1背包问题单源最短路问题最大团问题下一篇 上一篇 算法设计与分析复习–回溯法(二) 分支界限法性质 分支界限法是按广度优先策略或最小耗费优先遍历问题的解空间树。 搜索解空间: 子集树排列树 …...
Https攻击怎么防御
随着互联网技术的发展,网站所遭受的网络攻击频率也在不断上升。某种程度上,我们可以说互联网上的每个网站都容易遭受安全攻击。因为网络攻击者最主要的动机是求财。无论你运营的是电子商务项目还是简单的小型商业网站,潜在攻击的风险就在那里…...
网络知识学习(笔记二)
ios模型规定的网络模型一共有7层,但是实际使用过程中,4层的TCP/IP模型是经常使用的,网络知识学习笔记里面也是基于4层TCP/IP模型进行分析的,前面已经讲了:(1)物理层,(2&a…...
万字解析设计模式之组合模式、亨元模式
一、组合模式 1.1概述 组合模式是一种结构型设计模式,它允许将对象组合成树形结构,以表示“部分-整体”的层次结构。组合模式使得客户端可以一致地对待单个对象和对象组合,从而将复杂的层次结构展现为一个统一的树形结构。 在组合模式中&…...
HTTP之常见问答
1:HTTP/1.1 如何优化? :尽量避免发送 HTTP 请求;通过缓存技术,使用请求的 Etag 参数来处理判断缓存过期等问题,类似304状态码就是告诉客户端,缓存有效还能继续使用 :在需要发送 HTTP…...
java伪共享问题
参考文章 https://blog.csdn.net/qq_45443475/article/details/131417090 产生原因 cpu 与内核数据交换的单位是 cache 行,多核 cpu 的高速缓存在对同一个变量进行修改时由于缓存一致性协议导致对应的缓存失效。 缓存行的大小 cpu 架构有关系,如果是 …...
【Ubuntu】Ubuntu arm64 部署 Blazor Server 应用
部署步骤 发布安装运行环境:dotnet-sdk(必装)、aspnetcore-runtime、dotnet-runtime安装证书设置环境变量:临时变量、当前用户永久变量、所有用户的永久变量运行:终端运行、后台运行 基本情况 开发系统环境 系统&am…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
