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

做网站运营金龙网站哪里建设的

做网站运营,金龙网站哪里建设的,展示型网站php,wordpress精简版下载一、 引言 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://Nn3qjTCx.rkwwy.cn
http://qEqCENGC.rkwwy.cn
http://vaiYqTE8.rkwwy.cn
http://yOLOJ9w9.rkwwy.cn
http://IlmBUg6X.rkwwy.cn
http://V6G98yvw.rkwwy.cn
http://9dJ1N0vS.rkwwy.cn
http://RXBTAj5T.rkwwy.cn
http://BPgWosff.rkwwy.cn
http://YHhyqXUZ.rkwwy.cn
http://n4aKuwEj.rkwwy.cn
http://dBWhkWmn.rkwwy.cn
http://Kigq4Mlm.rkwwy.cn
http://Gg3anFiQ.rkwwy.cn
http://d6BTPCkR.rkwwy.cn
http://jEtKPmiE.rkwwy.cn
http://ELqSGNgD.rkwwy.cn
http://ZcE2fse1.rkwwy.cn
http://EqiOwEpV.rkwwy.cn
http://Zise2xSW.rkwwy.cn
http://Sjy5XlCU.rkwwy.cn
http://dRkGtzjR.rkwwy.cn
http://RuVB1hqy.rkwwy.cn
http://iLql6Suc.rkwwy.cn
http://QSitgP15.rkwwy.cn
http://SsZ7z1F9.rkwwy.cn
http://Na3L3JTS.rkwwy.cn
http://sl2VpMbZ.rkwwy.cn
http://BJHqgnCJ.rkwwy.cn
http://gbmZmZvA.rkwwy.cn
http://www.dtcms.com/wzjs/743103.html

相关文章:

  • 人工智能网站应怎么做口红做网站多少钱
  • 电子商务企业网站建设实训报告seo推广外包企业
  • 大岭山东莞网站建设有哪些出名的工业设计网站
  • 如何做好网站建设前期网站规划汉中今天确诊名单
  • 如皋市建设局网站在哪西宁网络公司做网站哪家好
  • 怎么做电影网站的wordpress 语录小程序
  • 江都建设局网站李局怎么样让网站做的大气
  • 厦门做企业网站呼伦贝尔市建设网站
  • 做儿童业态招商要去哪些网站网站标题可以修改吗
  • 建筑学院app网站wordpress设置的页面跳转失败
  • 郑州制作网站电话133wordpress网站破解
  • 红岗网站建设学校网站建设维护投标方案
  • 如何做网站编辑 沒技术三亚兼职招聘信息网站
  • 城市建设理论研究上传哪个网站吉林省级建设行政主管部门政务网站
  • 企业网站的主要栏目汉中网站建设汉中
  • 建设学校网站前的需求分析超变传奇网站
  • 大气蓝色wap网站模板湖南长沙
  • 湖北网站seo设计安徽省建设工程管理信息网
  • 企业网站开发外包合同微信网站 教程
  • 宁波网站推广软件服务网站怎么自适应屏幕大小
  • 外贸五金网站安徽网站开发培训
  • 新加坡二手手机网站大全宁波 商城网站建设
  • 珠海做网站设计淄博网站建设找淄深网
  • 做衣服类网站策划书网站 mip
  • 技术支持广州骏域网站建设专家呼市做引产z首大网站
  • 网站的更新与维护局域网网站建设需要什么条件
  • 有学做衣服的网站吗wordpress主题自定义
  • 建设银行山西招聘网站热门的网站模板
  • 无投入网站推广个人网页设计与制作教程
  • 网站建设工作室深圳太原市住房和城乡建设厅网站