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

长沙精品网站制作哪家培训机构好

长沙精品网站制作,哪家培训机构好,免备案网站制作,游戏制作器一、 引言 SQL死锁是一个常见且复杂的并发控制问题。当多个事务在数据库中互相等待对方释放锁时,就会形成死锁,从而导致事务无法继续执行,影响系统的性能和可用性。死锁不仅会导致数据库操作的阻塞,增加延迟,还可能对…

一、 引言

SQL死锁是一个常见且复杂的并发控制问题。当多个事务在数据库中互相等待对方释放锁时,就会形成死锁,从而导致事务无法继续执行,影响系统的性能和可用性。死锁不仅会导致数据库操作的阻塞,增加延迟,还可能对系统的稳定性和响应速度产生严重影响。因此,了解死锁的成因、识别死锁的方式以及采取有效的防范和解决措施,对于数据库管理员和开发人员而言,具有重要的实践意义。本文将根据一次线上SQL死锁的真实案例刨析发生的机制、如何检测死锁及常见的解决策略,以帮助提高数据库系统的效率和可靠性。

二、线上SQL死锁的背景

之前自己参与过一个农业类项目,在项目初期,我们是没有将读写表分离的,而是基于一个主库完成读写操作。后面随着业务方的推广业务量逐渐增大,我们偶尔会收到系统的异常报警信息,DBA 通知我们数据库出现了死锁异常。业务开始是比较简单的,就是新增订单、修改订单、查询订单等操作,那为什么会出 现死锁呢?经过日志分析,我们发现是作为幂等性校验的一张表经常出现死锁异常。

接下来我将在本地复现该问题,帮助我们更好的去理解SQL死锁的原因。

首先,创建一张订单记录表,该表主要用于校验订单重复创建:

CREATE TABLE `order_record` (`id` int(11) NOT NULL AUTO_INCREMENT,`order_no` int(11) DEFAULT NULL,`status` int(4) DEFAULT NULL,`create_date` datetime(0) DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,INDEX `idx_order_status`(`order_no`,`status`) USING BTREE
) ENGINE = InnoDB

为了能重现该问题,我们先将事务设置为手动提交。MySQL 数据库默认情况下是自动提交事务,我们可以通过以 下命令行查看自动提交事务是否开启:

先将 MySQL 数据库的事务提交设置为手动提交,我们可以看见此时已经改为手动提交了。

当时订单在做幂等性校验时,先是通过订单号检查订单是否存在,如果不存在则新增订单记录。 知道具体的逻辑之后,我们再来模拟创建产生死锁的运行 SQL 语句。首先,我们模拟新建两个订单,并按照以下顺序执行幂等性校验 SQL 语句

事务A事务B
BEGIN;BEGIN;
select id from order_record where order_on = 4 for update;  // 检查是否存在order_no = 4的订单
select id from order_record where order_on = 5 for update;  // 检查是否存在order_no = 5的订单

insert into order_record (order_no,states,create_date) values (4,1,'2025-03-20 15:30:25');  // 如果没有则插入信息

此时,锁等待 .......

insert into order_record (order_no,states,create_date) values (5,1,'2025-03-20 15:30:25');  // 如果没有则插入信息

此时,锁等待 .......

commit; (未完成)commit; (未完成)

此时,我们会发现两个事务已经进入死锁状态。我们可以在 performance_schema 数据库 中查询到具体的死锁情况,如下图所示:

你可能会想,为什么 SELECT 要加 for update 排他锁,而不是使用共享锁呢?试 想下,如果是两个订单号一样的请求同时进来,就有可能出现幻读。也就是说,一开始事务 A 中的查询没有该订单号,后来事务 B 新增了一个该订单号的记录,此时事务 A 再新增一条该订单号记录,就会创建重复的订单记录。面对这种情况,我们可以使用锁间隙算法来防 止幻读。

三、产生死锁的原因

在开始问题之前我们先来回想一下行锁的具体实现算法有那些?行锁的具体实现算法有三种:record lock、gap lock 以及 next-key lock。record lock 是专门对索引项加锁;gap lock 是对索引项之间的间隙加锁;next-key lock 则是前面两 种的组合,对索引项以其之间的间隙加锁。

只在可重复读或以上隔离级别下的特定操作才会取得 gap lock 或 next-key lock,在 Select、Update 和 Delete 时,除了基于唯一索引的查询之外,其它索引查询时都会获取 gap lock 或 next-key lock,即锁住其扫描的范围。主键索引也属于唯一索引,所以主键 索引是不会使用 gap lock 或 next-key lock。 在 MySQL 中,gap lock 默认是开启的,即 innodb_locks_unsafe_for_binlog 参数值是 disable 的,且 MySQL 中默认的是 RR 事务隔离级别。

当我们执行以下查询 SQL 时,由于 order_no 列为非唯一索引,此时又是 RR 事务隔离级 别,所以 SELECT 的加锁类型为 gap lock,这里的 gap 范围是 (4,+∞)。

SELECT id FROM order_record where order_no = 4 for update

执行查询 SQL 语句获取的 gap lock 并不会导致阻塞,而当我们执行以下插入 SQL 时,会 在插入间隙上再次获取插入意向锁。插入意向锁其实也是一种 gap 锁,它与 gap lock 是 冲突的,所以当其它事务持有该间隙的 gap lock 时,需要等待其它事务释放 gap lock 之 后,才能获取到插入意向锁。

以上事务 A 和事务 B 都持有间隙 (4,+∞)的 gap 锁,而接下来的插入操作为了获取到插 入意向锁,都在等待对方事务的 gap 锁释放,于是就造成了循环等待,导致死锁。

insert into order_record (order_no,states,create_time) values (5,1,'2025-03-20 15:30:25'); 

四、避免死锁的措施

知道了死锁问题源自哪儿,就可以找到合适的方法来避免它了。

避免死锁最直观的方法就是在两个事务相互等待时,当一个事务的等待时间超过设置的某一 阈值,就对这个事务进行回滚,另一个事务就可以继续执行了。这种方法简单有效,在 InnoDB 中,参数 innodb_lock_wait_timeout 是用来设置超时时间的。

另外,我们还可以将 order_no 列设置为唯一索引列。虽然不能防止幻读,但我们可以利用 它的唯一性来保证订单记录不重复创建,这种方式唯一的缺点就是当遇到重复创建订单时会抛出异常。

五、预防死锁

解决死锁的最佳方式当然就是预防死锁的发生了,我们平时编程中,可以通过以下一些常规 手段来预防死锁的发生:

1. 在编程中尽量按照固定的顺序来处理数据库记录,假设有两个更新操作,分别更新两条 相同的记录,但更新顺序不一样,有可能导致死锁;

2. 在允许幻读和不可重复读的情况下,尽量使用 RC 事务隔离级别,可以避免 gap lock 导 致的死锁问题;

3. 更新表时,尽量使用主键更新;

4. 避免长事务,尽量将长事务拆解,可以降低与其它事务发生冲突的概率;

5. 设置锁等待超时参数,我们可以通过 innodb_lock_wait_timeout 设置合理的等待超时 阈值,特别是在一些高并发的业务中,我们可以尽量将该值设置得小一些,避免大量事务等 待,占用系统资源,造成严重的性能开销。

六、小结

数据库发生死锁的概率并不是很大,一旦遇到了,就一定要彻查具体原因,尽快找出解决方案,我们只有先对 MySQL 的 InnoDB 存储引擎有足够的了解,才能剖析出造成死锁的具体原因。

http://www.dtcms.com/wzjs/206786.html

相关文章:

  • seo排名赚挂机靠谱吗网站怎么优化排名靠前
  • 阳江 网站建设班级优化大师下载安装app
  • 长沙网站开发推荐新闻头条最新消息
  • 温州做阀门网站公司卢镇seo网站优化排名
  • 360做网站运营培训
  • 西部数码网站管理助手 绑定域名免费网络项目资源网
  • 做网站i3够用吗搜索引擎推广的方法有
  • 想学做网站如何制作网站二维码
  • 网站开发甘特图女教师遭网课入侵视频
  • 网站建设机器人湖南正规关键词优化
  • 加盟型网站合肥seo优化公司
  • wordpress 社会交流厦门seo推广公司
  • 西瓜网站建设7个湖北seo网站推广策略
  • wordpress整站cdn网址大全导航
  • wordpress5.1.1编辑器还原桌子seo关键词
  • 网站管理员容易做吗百度竞价返点开户
  • 微商城网站建设平台合同凡科网站官网
  • 写网站论文怎么做的长沙网站优化体验
  • 淄博网站建设设计做电商一个月能挣多少钱
  • 深圳西乡网站建设百度关键词热度
  • 迪奥官网网站做的好吗网赌怎么推广拉客户
  • 用什么工具做网站视图seoul怎么读
  • 武汉做网站哪里好网络营销的用户创造价值
  • wordpress建立网站搜索引擎营销的成功案例
  • 武汉开发网站建设怎样推广自己的产品
  • 哪个网站可以做担保交易百度度小店申请入口
  • 网站建设纟金手指下拉壹陆上海抖音推广
  • 个性化网站有哪些百度搜索指数和资讯指数
  • 装潢设计学校百度词条优化
  • wordpress 外贸 模板百度seo关键词排名查询