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

关于MySQL数据库连接超时问题及解决办法

前言

1 为什么要使用锁?和事务有什么关系

使用锁,是为了保证事务的正常进行。举一个例子 事务A 和事务B 都要对 student 表中的某一个字段进行操作。事务A 进行查询操作,而事务B,则是对数据进行修改,如果 我不加锁 约束的话,那么事务A 前后查询的数据 不一致。不符合事务的一致性【事务前后的状态保持一致】

2 锁等待超时是什么意思?

两个或多个事务同时操作数据库中表的某一个字段,但已经持有锁的事务 长时间没有提交,释放锁。导致被等待的事务,等待锁释放时间超过规定超时时间,而导致 数据库主动和事务失去联系

举一个例子: 事务A 和事务B 都要对 student 表中的某一个字段进行操作。事务A 进行查询操作,而事务B,则是对数据进行修改 我现在给事务A添加排他锁 【功能:只要有一个事务进来了,不允许其他事务再操作】 。正常情况下,只有等 事务A 查询结束,事务提交成功,事务B才可以修改。但问题是 事务A查询 时间或者说查询语句的执行时间,比较久,锁一直没有释放,导致 事务B 因为长时间等待锁释放,超时。


“锁等待超时的本质是:多个事务竞争同一把锁时,持有锁的事务未及时释放,等待锁的事务在超过数据库设定的「锁等待超时阈值」(如 InnoDB 的innodb_lock_wait_timeout)后,数据库为避免死锁扩散,主动终止等待事务并抛出错误(如 MySQL 错误码 1205)。”


问题:锁等待,超时


解决办法:

1 延长超时 时间 ,在配置数据源时

注意:延长超时时间,只是一个治标不治本的方法。只是通过延长事务等待锁的时间。究其根本,还是找到  事务为什么没有提交,锁为什么没有释放的原因。

如下图所示:


2  查看待办表的索引,同时为达成目的 比如说根据 AD_BI_NO 条件修改 ,可以添加索引

注意:使用索引,是为了提高查询效率,降低全表查询,锁的颗粒度。从之前的表级锁 降低为行级锁。

-------查看待办表的索引

show index from wf_approve;

----- 为条件【查询/修改】新增索引

CREATE INDEX idx_wf_approve_ad_bi_no ON wf_approve(AD_BI_NO);

场景1 :当新增索引后,“若执行UPDATE wf_approve SET status=1 WHERE AD_BI_NO='xxx',索引:idx_wf_approve_ad_bi_no 后,SQL 会精准锁对应行,减少锁等待。”

  • 新增索引后,用explain 关键字 查看 SQL 是否走索引(避免索引失效);
  •  比如说:执行 explain UPDATE wf_approve SET status=1 WHERE AD_BI_NO='xxx' 


3 debug 定位 + 锁查询 SQL
  •  明确 自己要做什么 ?

举一个例子:我需要先添加一条甩项数据,当甩项 工作流走完,触发反射方法,对其工作流节点和状态 进行调整,从01责任人 修改为 甩项。这是我的目的 这一过程中,通过debug 方式 ,检查每一个环节,观察具体是哪里, 导致数据库连接超时,同时
通过执行 ,下面的sql语句 ,观察 是哪个事务 和目标表 相关联 并且 正在持有锁,未释放。

-- 查看 mis_saas 数据库中持有锁和等待锁的详细信息

SELECT-- 数据库和表信息dl.OBJECT_SCHEMA AS 数据库名,dl.OBJECT_NAME AS 表名,-- 锁基本信息dl.LOCK_TYPE AS 锁类型,dl.LOCK_MODE AS 锁模式,dl.LOCK_STATUS AS 锁状态,dl.LOCK_DATA AS 锁定数据,-- 事务信息itr.trx_id AS 事务ID,itr.trx_mysql_thread_id AS 线程ID,itr.trx_started AS 事务开始时间,itr.trx_state AS 事务状态,itr.trx_query AS 执行的SQL语句,-- 锁等待相关信息dlw.REQUESTING_ENGINE_LOCK_ID AS 请求锁ID,dlw.BLOCKING_ENGINE_LOCK_ID AS 阻塞锁ID
FROMperformance_schema.data_locks dl-- 关联事务表JOIN information_schema.INNODB_TRX itrON CAST(itr.trx_id AS UNSIGNED) = dl.ENGINE_TRANSACTION_ID-- 关联锁等待关系表LEFT JOIN performance_schema.data_lock_waits dlwON dl.ENGINE_LOCK_ID = dlw.REQUESTING_ENGINE_LOCK_IDOR dl.ENGINE_LOCK_ID = dlw.BLOCKING_ENGINE_LOCK_ID
WHEREdl.OBJECT_SCHEMA = 'mis_saas'  -- 只查询 mis_saas 数据库
ORDER BYitr.trx_started;  -- 按事务开始时间排序
  • 代码中,提到的数据表

  • 执行结果

比如 “锁状态为GRANTED的是持有锁的事务,WAITING的是等待锁的事务”;“锁定数据为1表示锁的是 id=1 的行”;
- 给出 “后续操作”:查到阻塞事务后,用KILL 线程ID(线程 ID 来自trx_mysql_thread_id)终止未释放锁的事务。


4 优化代码

比如;对一张表,查了很多次,改了很多次,都可以整合为一次去查询或修改,

5 如果一个功能中,涉及到很多表的操作,可以考虑,对一些操作,重新开一个新的事务

6 对于导致数据库连接超时的操作,可以考虑等主事务,事务提交结束,再执行

主事务提交后执行回调逻辑(如后续的数据库操作、消息发送等),可以通过 TransactionSynchronizationManager 注册事务同步器

注意:该方法基于 Spring 的事务同步机制,需在 Spring 项目中使用;

示例代码

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {@Overridepublic void afterCommit() {// 更新和删除 wf_approve 表的操作}
});

优点:即使afterCommit方法中的sql语句 出现问题,也不会影响 主事务的结果
缺点:回调逻辑(更新 / 删除 wf_approve)不在原事务中,而是在事务提交后异步执行。
如果回调执行时,其他事务恰好需要操作 wf_approve 表的同一条记录,可能因锁竞争导致超时。

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

相关文章:

  • AR智慧运维系统介绍
  • vue项目打包后dist部署到Nginx
  • 性能测试-jmeter9-直连数据库
  • 深度学习篇---模型组成部分
  • 财务文档处理优化:基于本地运行的PDF合并解决方案
  • 【51单片机】【protues仿真】基于51单片机压力测量仪系统
  • wpf触发器
  • Dify 从入门到精通(第 73/100 篇):Dify 的高级 RAG 优化(高级篇)
  • 调制端Phase Shift Discriminator(PSD)算法原理
  • 数据结构从青铜到王者第二十话---Map和Set(3)
  • windows安装PostgreSQL 和TimescaleDB
  • 数据结构:顺序栈与链栈的原理、实现及应用
  • 集成 Node.js 模块:文件系统与网络操作
  • 深入理解 Java 集合框架:底层原理与实战应用
  • 数据结构——二叉树+堆
  • .gitignore 文件为什么无效。
  • 开学季,老师如何用阅兵仪式激励学生?
  • PNP具身解读——RSS2025论文加州伯克利RLDG: 通过强化学习实现机器人通才策略提炼。
  • 在DDPM(扩散模型)中,反向过程为什么不能和前向一样一步解决,另外实际公式推导时反向过程每一步都能得到一个预测值,为什么还要一步一步的推导?
  • GEM5学习(4): 运行全系统模式的ARM系统
  • Docker 运行 PolarDB-for-PostgreSQL 的命令,并已包含数据持久化配置
  • 梅赛德斯-AMG PETRONAS F1车队携手SAP Cloud ERP:以数字化驱动精确与高效
  • HTML全屏功能实现汇总
  • 缠论笔线段画线,文华财经期货指标公式,好用的缠论指标源码
  • 从全栈开发到微服务架构:一位Java工程师的实战经验分享
  • 突破闭集限制:3D-MOOD 实现开集单目 3D 检测新 SOTA
  • Cesium 实战 - 自定义纹理材质 - 箭头流动线(图片纹理)
  • Corona 13 渲染器安装与使用教程(适用于3ds Max 2016–2026)
  • 【LeetCode热题100道笔记】搜索旋转排序数组
  • 认知诊断模型发展与NeuralCD框架笔记