首页 > 其他分享 >Lock wait timeout exceeded; try restarting transaction 问题分析

Lock wait timeout exceeded; try restarting transaction 问题分析

时间:2024-04-13 17:22:06浏览次数:24  
标签:transaction name Lock try innodb timeout mysql stock wait

问题描述

在项目中有一个 MySQL 数据库归档程序,每天会定时跑,在归档逻辑中,会涉及到对大表的查询(根据创建时间查询,它是索引),这个过程中会锁数据(行级锁),然后我们插入新的数据就会报错:获取锁超时

Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:123)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
	at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:371)

问题模拟

创建表及数据准备,这里我们使用的 MySQL 版本为 8.0

CREATE TABLE `tb_product` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(20) DEFAULT NULL COMMENT '商品名称',
  `stock` int DEFAULT NULL COMMENT '库存量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `tb_product` (`name`,`stock`) VALUES ('test',10);
INSERT INTO `tb_product` (`name`,`stock`) VALUES ('测试',4);
INSERT INTO `tb_product` (`name`,`stock`) VALUES ('小米手机',50);

查看 锁等待时间,默认是50秒

show variables like 'innodb_lock_wait_timeout';

这里我们修改为5秒

docker cp mysql-01:/etc/mysql/my.cnf .
vim my.cnf
# 添加如下内容
innodb_lock_wait_timeout=5
docker cp my.cnf mysql-01:/etc/mysql/my.cnf
docker restart mysql-01

注意:innodb_lock_wait_timeout 此参数仅对 innodb存储引擎的表 且 行级锁 有效

@Transactional
@PostMapping("testMysql1")
public Object testMysql() throws InterruptedException {
    List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select * from tb_product for update");
    Thread.sleep(300_000);
    return mapList.toString();
}

通过开启事务及for update来模拟一个行级锁。

@PostMapping("testMysql2")
public Integer testMysql2(String name, int stock) {
    jdbcTemplate.update("insert into tb_product(name,stock) values(?,?)", name, stock);
    return jdbcTemplate.queryForObject("select last_insert_id()", Integer.class);
}

先调用第一个接口,再调用第二个,这个时候就会报上面的错误。

问题排查

锁情况排查核心表

information_schema.innodb_trx          # 正在运行的事务信息。
sys.innodb_lock_waits                  # 处于锁等待的关联事务信息,这是个视图,不是表。
select * from sys.innodb_lock_waits limit 10; # sql_kill_blocking_connection 字段
kill 52; # 将阻塞住的连接 kill 掉

问题原因

根本原因就是我们对一个大表执行了耗时的查询,然后我们又要对这个表进行插入或更新,就会出现这个问题。

解决方案

将表的耗时查询和插入更新隔离开来,查询走从库,插入更新走主库,这样就不会有这个问题了。

参考

MySQL8.0锁情况排查,你学会了吗?
MySQL事务锁等待超时 Lock wait timeout exceeded;
排查和解决:Lock wait timeout exceeded; try restarting transaction
数据库作业——模拟表级锁示例和行级锁示例

标签:transaction,name,Lock,try,innodb,timeout,mysql,stock,wait
From: https://www.cnblogs.com/strongmore/p/18113761

相关文章

  • 一种新的姿势:程序try/catch抛出异常之绕过canary pwn121
    一种新的姿势:程序try/catch抛出异常之绕过canary我前面发了不少关于绕过canary的姿势,先总结一下,现在绕过canary的姿势有泄露,爆破,格式化字符串绕过,多线程劫持TLS绕过,stack_smashing,今天介绍一种新的姿势,就是程序处理异常时,如果异常被上一个函数的catch捕获,那么上个函数的rbp就会......
  • windmill Airplane&Superblocks&Retool&Prefect&Airflow 可选工具
    现在调度工具是越来越多了,而且集成的能力也越来越强大了windmill是一个很不错的workflow调度平台功能很强大特性可扩展的执行runtime,支持跨语言代码执行强大的调度器,支持基于低代码以及yaml模式通过appbuilder使用低代码或者js框架开发面向数据的dashboards智能依赖以......
  • 30 天精通 RxJS (16):Observable Operators - catch, retry, retryWhen, repeat
    我们已经快把所有基本的转换(Transformation)、过滤(Filter)和合并(Combination)的operators讲完了。今天要讲错误处理(ErrorHandling)的operators,错误处理是异步行为中的一大难题,尤其有多个交错的异步行为时,更容易凸显错误处理的困难。就让我们一起来看看在RxJS中能如何处理......
  • npm,registry,镜像源,npm切换源,yarn,cnpm,taobao,nrs
    描述我们在使用node的npm下载依赖的时候,往往下载速度很慢,那是因为npm默认的是npm处于国外的官方镜像源。所以需要切换到国内的镜像源来加速依赖下载。所以本文推荐一款简单好用npm镜像源管理器,可以方便开发者管理自己的镜像源。推荐:npm-registry-nrs......
  • guava-retrying
    https://github.com/rholder/guava-retrying ##Whatisthis?Theguava-retryingmoduleprovidesageneralpurposemethodforretryingarbitraryJavacodewithspecificstop,retry,andexceptionhandlingcapabilitiesthatareenhancedbyGuava'spredi......
  • Python中的错误处理 - 使用try、except、else和finally进行解释,并附带代码示例
    最近,我的经理委派我创建一个自动报告。我设计的报告非常简单。它包括一些来自数据库的数字和一些基本的数学运算。我很兴奋最终可以向公司展示我的惊人的Python技能。我完成并交付了产品。一切都很顺利。至少,直到大约两周后。我的报告由于除以零错误而随机失败了。来了个笑声轨道......
  • Spring-Retry
     https://github.com/spring-projects/spring-retryThisprojectprovidesdeclarativeretrysupportforSpringapplications.ItisusedinSpringBatch,SpringIntegration,andothers.Imperativeretryisalsosupportedforexplicitusage.QuickStartThi......
  • CLOCK_MONOTONIC 与 CLOCK_REALTIME 区别
    CLOCK_MONOTONIC指的是monotonictime,而CLOCK_REALTIME指的是walltime。monotonictime的字面意思是单调时间,实际上,指的是系统启动之后所流逝的时间,这是由变量jiffies来记录的,当系统每次启动时,jiffies被初始化为0,在每一个timerinterrupt到来时,变量jiffies就加上......
  • 【报错】Error: https://registry.npmmirror.com.tgz: tunneling socket could not be
    报错信息:Error:https://registry.npmmirror.com/bytes/download/bytes-3.0.0.tgz:tunnelingsocketcouldnotbeestablished,cause=connectECONNREFUSED127.0.0.1:31181详细报错:Error:https://registry.npmmirror.com/bytes/download/bytes-3.0.0.tgz:tunnelingsoc......
  • try-with-resource的使用
    try-with-resources支持从Java7开始的所有后续版本。只有实现了AutoCloseable或Closeable接口的资源才能用于try-with-resources。可以在括号内声明多个资源,用分号分隔。如果try块中抛出了异常,并且close()方法也抛出了异常,那么抛出的异常将是try块中的异常......