背景:

曾经的一位同事问我:"数据库只有并发INSERT 操作,会造成死锁么?",我没有太多思考地回答"不会",但真的不会吗?

测试:

--=================================
--创建测试表
CREATE TABLE TB3
(
ID INT PRIMARY KEY
)
GO
--===================================
--新开回话1
BEGIN TRAN
INSERT INTO TB3
SELECT 2
WAITFOR DELAY '0:0:10'
INSERT INTO TB3
SELECT 1
--===================================
--新开回话2
BEGIN TRAN
INSERT INTO TB3
SELECT 1 WAITFOR DELAY '0:0:10'
INSERT INTO TB3
SELECT 2

在上面的两个回话中,由于主键(唯一约束)的限制,相同的key对应相同的lock Resource,导致需要等待对方所获取的lock Resource,从而引发死锁

而如果将主键修改为非唯一索引,则不会引发死锁,相同的key对应不相同的lock Resource,因此不会造成相互等待也不引发死锁。

--====================================================================

--华丽的PS

对于最常见的死锁场景:

事务1 获取表TB1上的资源,请求表TB2上的资源

事务2 获取表TB2上的资源,请求表TB1上的资源

很多开发人员都会有意识保证各个事务访问不同表的顺序,从而避免此类死锁的发生,但很少会考虑对相同表的访问顺序,尤其在输入值被参数化的情况,如在下面的情况下:

BEGIN TRAN
UPDATE TB1
SET C2=@P2
WHERE C1=@P1 UPDATE TB1
SET C2=@P3
WHERE C1=@P3 COMMIT

在考虑是否会引发死锁时,我们除了分析当前语句外,还得检查这些语句所涉及到的表相关对象:触发器+外键+索引,还需分析其他业务场景的潜在影响。

PS:很多我们自认为正确的小结论,洗洗(细细)分析下,根本就是错误,而这些西奥结论,可能造成很恶劣影响。

--========================================================

照例妹子镇贴

图片来源于一豆瓣友邻

Transaction And Lock--唯一索引下INSERT导致的死锁的更多相关文章

  1. mysql 5.6 read-committed隔离级别下并发插入唯一索引导致死锁一例

    今天,某个环境又发生了死锁,如下: *** (1) TRANSACTION:TRANSACTION 735307073, ACTIVE 0 sec insertingmysql tables in u ...

  2. MySQL中因为unique key 非空唯一索引存在导致修改主键失败案例

    研发在早期的设计中,由于设计方面的问题,导致在设计表结构的时候,有个表有非空唯一索引而没有主键 在InnoDB存储引擎中,如果没有主键的情况下,有非空唯一索引的话,非空唯一索引即为主键. 那么这就会有 ...

  3. 对于唯一索引使用唯一条件搜索, InnoDB 只锁定找到的index record,不是它之前的区间

    | test100 | CREATE TABLE `test100` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', `phoneNo` ...

  4. MySQL 5.6.35 索引优化导致的死锁案例解析

    一.背景 随着公司业务的发展,商品库存从商品中心独立出来成为一个独立的系统,承接主站商品库存校验.订单库存扣减.售后库存释放等业务.在上线之前我们对于核心接口进行了压测,压测过程中出现了 MySQL ...

  5. Oracle索引梳理系列(七)- Oracle唯一索引、普通索引及约束的关系

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  6. 【译】SQL Server索引进阶第八篇:唯一索引

    原文:[译]SQL Server索引进阶第八篇:唯一索引     索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就 ...

  7. Sql Server 索引之唯一索引和筛选索引

    唯一索引(UNIQUE  INDEX) 当主键创建时如果不设置为聚集索引,那么就一定是唯一的非聚集索引.实际上,唯一索引,故名思议就是它要求该列上的值是唯一的.唯一索引能够保证索引键中不包含重复的值, ...

  8. mysql 区间锁 对于没有索引 非唯一索引 唯一索引 各种情况

    The locks are normally next-key locks that also block inserts into the "gap" immediately b ...

  9. SQL Server索引 - 聚集索引、非聚集索引、非聚集唯一索引 <第八篇>

    聚集索引.非聚集索引.非聚集唯一索引 我们都知道建立适当的索引能够提高查询速度,优化查询.先说明一下,无论是聚集索引还是非聚集索引都是B树结构. 聚集索引默认与主键相匹配,在设置主键时,SQL Ser ...

随机推荐

  1. 使用python发送邮件

    最近需要做一个功能,统计bug的数量,然后发邮件给指定人,所有就先要了解一下使用python发送邮件 代码如下: #coding: utf-8 import smtplib from email.MI ...

  2. Python property() 函数

    Python property() 函数  Python 内置函数 描述 property() 函数的作用是在新式类中返回属性值. 语法 以下是 property() 方法的语法: class pro ...

  3. springboot自定义消息转换器HttpMessageConverter

    在SpringMVC中,可以使用@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,底层这种灵活的消息转换机制就是利用HttpMessageCo ...

  4. python之面向对象之封装

    今天我们终于进入了面向对象,今天做一下面向的封装的总结 #面向对象的封装 #这里定义了一个类,名称为Role,object是所有类的父类 class Role(object): #这里是定义实例的属性 ...

  5. JAVA知识积累 JSP第一篇【JSP介绍、工作原理、生命周期、语法、指令、行为】

    什么是JSP JSP全名为Java Server Pages,java服务器页面.JSP是一种基于文本的程序,其特点就是HTML和Java代码共同存在! 为什么需要JSP JSP是为了简化Servle ...

  6. Web站点性能拨测脚本

    功能:检测自己本地访问目标网站的返回状态.访问质量信息 [root@localhost src]# cat get_site_status.sh #! /usr/bin/env bash if [[ ...

  7. Broadcast总结 service

    有时候离开应用就会接收不到系统的广播是因为系统默认发送的广播都会有一个参数 ntent startIntent = new Intent();startIntent.putExtra("pk ...

  8. LINQ to Entities 不支持 LINQ 表达式节点类型“ArrayIndex”。

    错误原因: bool res1 = S_ROLE_MENU_PURVIEWCODE_Manage.Delete(c => c.MPC_CODE == strs[0]); linq不能写strs[ ...

  9. Jmeter报文体包含过大附件导致请求报文发送失败的解决办法

    Jmeter中,HTTP request的报文体为一个附件时,如果附件过大,在发送请求报文的时候会失败,办法就是勾选“Use multipart/form-data for POST”

  10. jquery panel加载(dialog加载类似)

    项目情况: 主页面用引用了公共头文件(包含easui.min.js),使用easyui的dialog(href方式)打开窗口(被打开的窗口页面是纯html片段,无body元素等,也引入了公共头文件), ...