Transaction And Lock--唯一索引下INSERT导致的死锁
背景:
曾经的一位同事问我:"数据库只有并发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导致的死锁的更多相关文章
- mysql 5.6 read-committed隔离级别下并发插入唯一索引导致死锁一例
今天,某个环境又发生了死锁,如下: *** (1) TRANSACTION:TRANSACTION 735307073, ACTIVE 0 sec insertingmysql tables in u ...
- MySQL中因为unique key 非空唯一索引存在导致修改主键失败案例
研发在早期的设计中,由于设计方面的问题,导致在设计表结构的时候,有个表有非空唯一索引而没有主键 在InnoDB存储引擎中,如果没有主键的情况下,有非空唯一索引的话,非空唯一索引即为主键. 那么这就会有 ...
- 对于唯一索引使用唯一条件搜索, InnoDB 只锁定找到的index record,不是它之前的区间
| test100 | CREATE TABLE `test100` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', `phoneNo` ...
- MySQL 5.6.35 索引优化导致的死锁案例解析
一.背景 随着公司业务的发展,商品库存从商品中心独立出来成为一个独立的系统,承接主站商品库存校验.订单库存扣减.售后库存释放等业务.在上线之前我们对于核心接口进行了压测,压测过程中出现了 MySQL ...
- Oracle索引梳理系列(七)- Oracle唯一索引、普通索引及约束的关系
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- 【译】SQL Server索引进阶第八篇:唯一索引
原文:[译]SQL Server索引进阶第八篇:唯一索引 索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就 ...
- Sql Server 索引之唯一索引和筛选索引
唯一索引(UNIQUE INDEX) 当主键创建时如果不设置为聚集索引,那么就一定是唯一的非聚集索引.实际上,唯一索引,故名思议就是它要求该列上的值是唯一的.唯一索引能够保证索引键中不包含重复的值, ...
- mysql 区间锁 对于没有索引 非唯一索引 唯一索引 各种情况
The locks are normally next-key locks that also block inserts into the "gap" immediately b ...
- SQL Server索引 - 聚集索引、非聚集索引、非聚集唯一索引 <第八篇>
聚集索引.非聚集索引.非聚集唯一索引 我们都知道建立适当的索引能够提高查询速度,优化查询.先说明一下,无论是聚集索引还是非聚集索引都是B树结构. 聚集索引默认与主键相匹配,在设置主键时,SQL Ser ...
随机推荐
- Appium的inspector使用
使用inspectot可以对元素进行定位 1.设置appium的Android Settings,点击左上角的安卓图标进入安卓设置,注意设置时不要开启appium 说明: a)Application是 ...
- 利用简单的参数传递来实现单条查询的easyui-datagrid
前一阵子老师给出了一个题目, 说让设计个表格, 学生系统的, 可以查询学生的信息和成绩, 科目自己定, 数据库建表也自己定. 数据库的建表可是建的相当的简陋, 反正老师不是很满意, 后来数据表格做出来 ...
- 修改hosts,***
某些网站之所以在国内上不了,是因为dns受到干扰,无法解析出正确的ip地址. 可以在hosts文件中加入网站对应的正确ip地址,进行访问. 1.打开hosts文件, 路径为 C:\Windows\S ...
- Python property() 函数
Python property() 函数 Python 内置函数 描述 property() 函数的作用是在新式类中返回属性值. 语法 以下是 property() 方法的语法: class pro ...
- Pocket Cube
Pocket Cube http://acm.hdu.edu.cn/showproblem.php?pid=5983 Time Limit: 2000/1000 MS (Java/Others) ...
- python的协程和异步io【select|poll|epoll】
协程又叫做微线程,协程是一种用户态的轻量级的线程,操作系统根本就不知道协程的存在,完全由用户来控制,协程拥有自己的的寄存器的上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来后, ...
- 手机端图片预览和缩放js
转至:http://blog.sina.com.cn/s/blog_c342e3090102vcxu.html 1.手机端的图片选择和预览 <input type="file" ...
- C语言跳表(skiplist)实现
一.简介 跳表(skiplist)是一个非常优秀的数据结构,实现简单,插入.删除.查找的复杂度均为O(logN).LevelDB的核心数据结构是用跳表实现的,redis的sorted set数据结构也 ...
- Flask源码剖析详解
1. 前言 本文将基于flask 0.1版本(git checkout 8605cc3)来分析flask的实现,试图理清flask中的一些概念,加深读者对flask的理解,提高对flask的认识.从而 ...
- javabean为什么要实现序列化?
javabean为什么要实现序列化? 所谓的Serializable,就是java提供的通用数据保存和读取的接口.至于从什么地方读出来和保存到哪里去都被隐藏在函数参数的背后了.这样子,任何类型只要实现 ...