背景:

曾经的一位同事问我:"数据库只有并发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. Hibernate 序列生成主键

    @Entity @Table(name="TABLE_NAME") public class TableName implements Serializable { @Id @Ge ...

  2. python学习——sys.argv

    sys.argv[]:用于获取命令行参数,sys.argv[0]即所运行的代码自身的文件路径,因此真正的其他参数是从1开始 sys.argv[1]:表示第一个参数 sys.argv[1][2:]:表示 ...

  3. tortoise svn 请求的名称有效,但是找不到请求的类型的数据

    可能是博客园出bug了,现在无法放图,间断重复刷新十多次依然如故,弃之 这个问题是在安装完svn服务器(visual svn)后复制url,tortoise svn import 粘贴url后 出现的 ...

  4. UpdatePanel中弹出新窗口

    如果允许,在UpdatePanel中使用iframe即可,不允许的话,用下面的方法实现弹窗 要在UpdatePanel中使用FileUpload时,会遇到此问题,或者同类其它情况 <asp:Sc ...

  5. centos7下创建mysql5.6多实例

    一.mysql安装目录说明mysql5.6以二进制安装包安装在/data/mysql56下数据目录为/data/mysql56/data下配置文件为/etc/my.cnf下 二.多实例目录说明/mys ...

  6. html注释快捷键

    1.选中需要注释的内容--->ctrl+shift+/ 2.取消注释--->ctrl+shift+\

  7. OAuth2.0 Owin 授权问题

    http://www.cnblogs.com/dudu/p/4569857.html OAuth2.0 一.什么是OAuth OAuth是一个关于授权(Authorization)的开放网络标准,目前 ...

  8. ef linq 访问视图返回结果重复

    根据检测到的语句查询和linq查询出来的结果不一致,linq查询出重复的数据,原因不明,已改用ef直接查询视图,也许以后某一天突然就解决了,先mark下.

  9. final修饰符:

    知识点: 1.final关键字用于修饰类.变量和方法 2.有点类似C#里的 sealed 关键字,用于表示它修饰的方法.变量和类不可以再被改变 3.final修饰变量时,表示该变量一旦获取了初始值,就 ...

  10. Banner中文字怎么排版才好看?

    今天这命题,相信有很多人提出过疑问,一个好的文字排版会给你的作品增添色彩,我们先看看好的作品是怎样的. 看完这些图大家都能感觉出来这是一个好的作品,大家天生就对美和丑有一定的区分. 其实文字排版也好, ...