看三年的CRUD程序员如何解决数据库死锁的

线上MySQL死锁分析——索引设置不当导致的死锁 文章目录1. 背景2. MySQL InnoDB的锁机制2.1 MySQL中的锁类型2.2 行锁的加锁规则2.3 死锁检测机制3. 本文案例分析3.1 分析InnoDB status日志3.2 Explain 死锁SQL、查看表的索引信息3.3 查看业务代码3.4 实验验证猜想3.5 问题解决4. 如何预防死锁参考 1. 背景 9月4号负责的系统接入了在线诊断分析平台,其中的运行时Java异常追踪工具能够捕获并上报线上异常。接入后发现系统会频繁的产生org.springframework.dao.Deadl 阅读详情

问题出现

数据库死锁的问题不知道大家有没有见过,反正我干了三年多CRUD是第一次见。

接下来就一起来看看我遇到的这个死锁到底是怎样造成的?怎么解决的?

首先贴一下报错信息

### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: 
Deadlock found when trying to get lock; 
try restarting transaction; SQL []; 
Deadlock found when trying to get lock; 
try restarting transaction; 
nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: 
Deadlock found when trying to get lock; 
复制代码

当时的业务逻辑大概是这样的,如下图

现在给他简化一下

  • 两个接口A和B,分别会开始事务A和B,一条数据行d
  • 首先接口A会开启事务A去更新数据行d,拿到这条数据行的锁
  • 通过RPC调用接口B,接口A等待接口B的响应返回才能进行事务的提交
  • 接口B开启事务B去更新数据行d,但是数据行d的锁被事务A持有,事务B只能等待事务A释放锁才能进行数据的更新

这就是典型的相互等待造成的死锁,一个持有锁,一直无法释放;一个等待锁,一直获取不到。

那么,这个问题是如何解决的呢

经过跟同事及leader的沟通,大概给出三种方案

多线程

针对上面造成死锁的问题,可以将RPC的调用另起一个线程去执行;主线程去执行数据更新的操作。

  • 首先接口A不需要等待接口B的返回就可以提交事务
  • 然后就算接口B执行比较快:A事务还没有提交的时候,B接口就已经执行到更新数据的地方,这时候会堵塞;但是没关系,无论如何A事务都会提交事务,无非是快慢的问题
  • 所以上述的死锁就会被解决

但是这种方式就是万无一失么,有什么问题呢?

  1. 多线程执行RPC调用,无法获取响应结果(当然多线程也能获取结果,但是获取结果的话,事务A还是无法提交造成死锁,没有意义)。
  2. 无法判断接口的成功与否,就丧失了事务失败回滚的意义
  3. 多线程能解决上述问题的死锁问题,但是稍微复杂一点的多表交叉更新还是会出问题,如下图

对事务进行细化处理

把接口A中的事务进行细化拆分:

  • 将需要更新数据库的逻辑拆分成一个方法,并在方法调用的时候开启事务
  • 当细分的方法执行成功后,再去进行RPC调用

这个解决了响应无法返回的问题,但还是那个问题,如果RPC调用失败了,更新的数据无法回滚。

顺序处理(也是最终的处理方案)

上述死锁问题的解决

  • 先RPC调用接口
  • 再进行更新操作

另外,顺序处理也是能解决复杂一点的多事务的多表更新死锁问题的。

首先我们得保证两个或多个开启事务的接口,对数据库数据的处理尽量避免交叉更新,应该按顺序更新。

比如对多线程处理的第三个问题解决,如图

其他方案

大伙们还有其他比较好的方案么,欢迎来沟通讨论啊。

水货程序员之多线程踩坑记 ——浅谈 CRUD 工程师的多线程套路 作为一个每天从早到晚 CRUD 的工程师,多线程技术虽然不天天用,却也是不得不学的一部分。就算不写多线程,面试时“你对多线程的理解”这类问题也是绕不过去的坎。最糟糕的是,在实际项目中应用多线程技术时,由于理解不透彻,很容易掉进“水货程序员”们都踩过的那些坑。今天这篇文章,就是来帮各位小伙伴们理清多线程中的“雷区”有哪些,并总结了一些踩坑经验和避坑建议。希望在看完这篇之后,CRUD 工程师们也能稳稳当当地在多线程的世界里畅游!线程是进程中的执行单元,负责执行具体的代码。 阅读详情

相关推荐

全栈Web开发实践:CRUD与数据库集成

本文还有配套的精品资源,点击获取 简介:WebTechnologiesProject是一个深入展示现代Web技术项目,涵盖Node.js和Sequelize的后端开发,通过CRUD操作实现全栈功能。该项目不仅涉及前端和后端的互动,还包括数据库集成、RESTful API设计以及前端技术的使用。开发者将通过项目实践获得全面的Web开发知识,包括服务器端JavaScript编程...

weixin_26850469的博客 1734

工作一年,天天 CRUD,怎么破?

我感觉我现在更像是一名全栈 CRUD 工程师,应该怎么办?

努力做最接地气的编程干货分享,感谢关注 3932

【Coze 扣子案例】第 23 期・商业篇:一键获取精准商机,自动化招标信息查询与分析

通过地区和项目类型等多维度组合查询全国招标信息网数据,实现招标公告的快速定位。自动解析招标公告内容,提取关键信息,并生成结构化摘要。帮助企业高效获取精准商机,提升市场竞争力,降低人工成本,解决 “信息过载” 与 “精准匹配难” 的双重问题。

weixin_72689845的博客 1928

如何摆脱CRUD的困境? —— 改变思维,向上管理

作为一名程序员,我们在工作中经常会遇到“CRUD”的情况,特别是当工作了两三年后,很多人开始觉得编程仅仅是循环和条件语句的组合,已经失去了对工作的热情和兴趣。对架构图把自己不会的技术用点对架构图把自己不会的技术用点标注出来,在日常工作中有意识地去观察和积累,在业余时间不断地去学习和精进,把这些短板全部补齐。尝试改变往往会引发蝴蝶效应。当你愿意从项目整体的运维和架构设计的视角去优化本职工作,愿意利用业余时间不断提升自己的技术水平时,你就有机会为自己争取到不一样的工作内容和经验,从而跳出CRUD的怪圈。

weixin_50409347的博客 492

STM32F1的USB接口-自定义HID

设置USB VID:1155 PID :22352。

chilian12321的博客 839

避坑指南:麒麟系统ARM架构下PostGIS离线安装常见问题解析

本文深度解析了在国产麒麟系统ARM64架构下进行PostGIS离线安装的完整路径与核心避坑点。通过对比Docker容器化与源码编译两种部署方式的优劣,详细阐述了离线Docker环境搭建、ARM64镜像获取验证、容器化配置及常见故障排查的全流程,为在特殊环境下稳定部署空间数据库提供了一套可靠的实践指南。

Python的专栏 287

大专毕业,一年工作经验,每天都是CRUD。如何实现月薪从7k到10k?

今天的话,这篇文章,主要回答一些小伙伴的问题。不过这些问题的话,相信也是大部分小伙伴会遇到的,所有,你有必要看到最后哦! 01 我跟着视频做的项目会被面试官嫌弃不?是加分项不? 当然是加分项呢!不排除确实有的面试官不吃这一套,这个也看人。不过我相信大多数面试官都是能理解的,毕竟你在学校的时候实际上是没有什么获得实际项目经验的途径的。 别担心,大部分应届生的项目经验都是自己在网上找的或者像你一样买的付费课程跟着做的,极少部分是比较真实的项目。 从你能想着做一个实战项目来说,我觉得初衷是好的,确实也能真正学到

JavaGuide 6183

【ESP32设备通信】-LoRa通信

在本文中,我们将使用 Arduino IDE 将 ESP32 与 LoRa SX1278 (Ra-02) 模块连接起来。 我们将创建一个真实的示例项目,通过 LoRa 无线打开/关闭 LED 进行演示。

视觉与物联智能 1893

Java程序员:CRUD,你真的会了吗?

CRUD,增删改查,读写分离,主从架构,CQRS,读写锁,事务控制,SQL,DQL,DML

nshkfhwr的博客 1207

X书关键词协议搜索

【代码】X书关键词协议搜索。

Codeooo 博客 6380

华为OD机试双机位C卷-组装新的数组(Py/Java/C/C++/Js/Go)

华为OD机试(机考)双机位C卷 【组装新的数组】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - 组装新的数组。

qq_45776114的博客 1146

CRUD程序员

CRUD程序员”是软件开发领域中一个常见的称呼,通常指主要从事**增删改查(Create、Read、Update、Delete,简称CRUD)**这类基础数据操作开发的程序员。- 学习高级后端技术:分布式事务、微服务治理(如Spring Cloud)、分布式存储(MySQL分库分表、MongoDB)、搜索引擎(Elasticsearch)等。- 扩展技术栈:以CRUD为起点,学习分布式架构(如微服务、消息队列)、云原生(Docker、K8s)、前端全栈等,向全栈或架构师方向发展。

ZhuBin365的博客 1379

YOLOv8改进 | 主干篇 | 轻量级的低照度图像增强网络IAT改进YOLOv8暗光检测(全网独家首发)

本文给大家带来的改进机制是轻量级的变换器模型:Illumination Adaptive Transformer (IAT),用于图像增强和曝光校正。其基本原理是通过分解图像信号处理器(ISP)管道到局部和全局图像组件,从而恢复在低光或过/欠曝光条件下的正常光照sRGB图像。具体来说,IAT使用注意力查询来表示和调整ISP相关参数,例如颜色校正、伽马校正。模型具有约90k参数和约0.004s的处理速度,能够在低光增强和曝光校正的基准数据集上持续实现优于最新技术(State-of-The-Art, SOTA)

Snu77的博客 7966

搞定项目中死锁问题!java项目中常见的死锁与解决办法

在工作与日常开发中,事务对数据进行在增删查改(CRUD)操作难免会出现死锁情况,单体应用项目需要找出死锁原因还是比较容易,很多小伙伴在搭建复杂的微服务项目调用的时候经常出现死锁情况,多服务调用排查比较困难还是需要把业务熟悉做好逻辑梳理。数据库的死锁通常是由于多个数据库操作相互竞争锁资源,导致系统无法继续执行的情况。死锁发生的典型场景是两个或更多的事务在并发执行时,互相等待对方释放锁,最终导致每个事务都无法继续执行。博主经常遇到类似的问题,希望下面的这篇文章给您带来收获与解决意识。

qq_51747498的博客 2441

DSPy 入门: 再见提示,你好编程

DSPy("Declarative Self-improving Language Programs (in Python)",发音为 "dee-es-pie")[1] 是斯坦福大学 NLP 研究人员开发的 "基础模型编程 "框架。它强调编程而非提示,并将构建基于 LM 的管道从操作提示转向编程。因此,它旨在解决构建基于 LM 应用程序时的脆弱性问题。DSPy 还将程序的信息流与每一步的参数(提示和 LM 权重)分离开来,为构建基于 LM 的应用程序提供了更系统的方法。

具身机器人和通用AI 3488

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Laravel Database——数据库的 CRUD 操作源码分析

前言 当 connection 对象构建初始化完成后,我们就可以利用 DB 来进行数据库的 CRUD ( Create、Retrieve、Update、Delete) 操作。本篇文章,我们将会讲述 laravel 如何与 pdo 交互,实现基本数据库服务的原理。 run laravel 中任何数据库的操作都要经过 run 这个函数,这个函数作用在于重新连接数据库、记录数据库日志、数据库异常处理: protected function run($query, $bindings, Closure $callb

cangqiong_xiamen的博客 622

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

做了三年CRUD,面试被虐哭后我才明白:Java后端的技术壁垒到底在哪

深夜11点,程序员小张盯着屏幕上的"订单超卖"报警陷入沉思——这个看似简单的电商促销系统,在流量洪峰面前像纸糊的一样脆弱。上周的面试场景突然闪现:当面试官问起如何设计千万级并发的库存系统时,他支支吾吾说不出分布式锁的具体实现细节,只能尴尬地说"用Redis应该可以吧"。当你真正搞懂这些"深水区"技术时,那些曾让你夜不能寐的面试八股文,都会变成你攻城略地的利器。血泪教训:某物流公司采用最终一致性方案处理运单状态,结果在跨地域网络分区时,出现了"已签收"和"运输中"并存的灵异现象,直接导致客户投诉暴增。

微信公众号:互联网之路 534

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

数据库事务 - 怎样才能产生 互相等待 - 死锁,怎么解决

数据库事务 - 怎样才能产生 互相等待 - 死锁,如何解决 1. 最简单的死锁 最常见的死锁 是因为一个事务执行时间过长,而导致另外一个事务无法访问 被被该事务锁定的资源,最终超时而导致的死锁异常.这种情况无非有两种解决方案,一是性能调优。 二是当该事务遇到等待超时导致的死锁异常后,继续让该事务 re-try. 2. 互相等待 -- 死锁 这种 死锁的异常...

weixin_30570101的博客 452

解决死锁的SqlException通信缓存资源

我们Microsoft Sql 服务器上的数据库执行 CRUD 操作。为此,连接管理器(注册为范围服务)IDbConnection在请求范围内打开一个新连接;此连接用于执行删除、插入、更新或获取。对于插入/更新/删除,C# 行如下所示await connection.ExecuteAsync("", entity);对于GET请求,我们只需运行await connection.QueryFirstOrDefaultAsync("", entity);;有 5 种类型的实体(都呈现简单的非关系表)。他们都按

weixin_51392371的博客 854

AI时代程序员转型:从CRUD到AI Agent开发者

随着AI编程工具如GitHub Copilot和GPT-4的普及,传统编码工作正面临前所未有的挑战。AI在代码生成、知识检索和运维自动化方面展现出强大能力,迫使开发者重新思考自身价值。技术演进的核心在于理解AI-native架构和Agent开发技术栈,包括认知层的思维链原理、工具层的API封装标准化、记忆层的向量数据库应用,以及评估层的对抗性测试设计。掌握这些技能不仅能够提升开发效率,更能创造AI与人类协同的新型工作模式。数据显示,具备AI协同开发能力的工程师薪资涨幅显著,尤其在电商、金融等领域,AI Ag

weixin_29062823的博客 292

C3P0数据库连接池死锁问题

死锁的产生原理是:存在线程同时占有两个以上的连接对象的情况。  比如某连接池中有2个连接对象。  有两个线程分别占用了一个,又分别来申请另一个。这时由于连接池空,而两个线程本身都卡在连接池上,不可能释放原来占有的连接对象,这时产生死锁。  连接池死锁,会导致软件和数据库相关的部份无响应。比如登陆功能,会用数据库做用户校验,发生连接池死锁后,登陆功能会无法使用(点登陆按钮后,长时间无相应)。 策略...

qiuchaoxi的博客 2224

Android DB锁问题

如果一个线程已经在数据库上持有一个写事务(这会获得一个独占锁),其他任何尝试写入数据库或开启新事务的线程都将被阻塞,直到第一个线程完成事务(即提交或回滚)。如果可能,设计你的应用程序架构以使数据库访问局限于单个后台进程,然后通过AIDL、Messenger、Intent或其他IPC机制与其他进程进行通信,这样可以避免直接的多进程数据库访问。类似于锁定异常,如果数据库忙于处理其他线程的请求,尝试写入的线程可能会收到一个异常,表明数据库目前无法处理更多的事务。尽可能将事务保持在最短时间内,只包含必要的操作。

weixin_45681365的博客 1004

每天导入100万数据导致数据库死锁?

在高并发批量导入数据时,数据库死锁是一个非常常见但容易被忽视的问题。我们作为后端开发者,不能只会写 SQL,还需要理解数据库的锁机制并发控制和事务边界。死锁不一定是 bug,但一定是设计问题多线程写数据库时要控制主键访问顺序临时表 + 合并更新是最安全的方式避免使用“万能 SQL”(如)滥用。

2401_89221704的博客 716
上一篇: Java面试题大全(整理版)1000+面试题附答案详解,最全面详细,看完稳了
下一篇: 设计一个填充工具完美解决前后端甩锅的问题了
程序员职业指南
博客等级 码龄4年 2139粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值