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 ...
随机推荐
- python没有switch,可以用字典来替代
python没有switch,是因为可以用字典来替代,具体方法如下: def add(x,y): print(x+y)def subtraction(x,y): print(x-y)def multi ...
- access数据库收缩(压缩)
一般是因为表中有大量没用的数据,把没用的数据全部删除 菜单栏的“工具”——“数据库实用工具”——“压缩和修复数据库” OK啦
- springmvc使用list集合实现商品列表的批量修改
1将表单的数据绑定到List 1.1 需求 实现商品数据的批量修改. 1.2 需求分析 要想实现商品数据的批量修改,需要在商品列表中可以对商品信息进行修改,饼干且可以批量提交修改后的商品数据. 1.3 ...
- struts框架问题四之获取到值栈的对象
4. 问题四 : 如何获得值栈对象 * 获得值栈对象 有三种方法 * ValueStack vs1 = (ValueStack) ServletActionContext.getRequest().g ...
- Git 初始状操作指引
You have an empty repository To get started you will need to run these commands in your terminal. Ne ...
- winsock select 学习代码(1)
// SelectCli.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <winsock2.h> #incl ...
- ajax序列化表单,再也不用通过data去一个个的传值了
jQuery的serialize()方法通过序列化表单值,创建URL编码文本字符串,我们就可以选择一个或多个表单元素,也可以直接选择form将其序列化 这样,我们就可以把序列化的值传给ajax()作为 ...
- [GO]解决golang.org/x/ 下包下载不下来的问题
因为在项目中要使用到一个golang.org的包,但是因为墙的问题,官方方法已经无法使用,但是在github上存在一个镜像站可以使用,我们只需要将它克隆下来就可以正常使用了 mkdir -p $GOP ...
- 03-vue-router
前端路由的实现原理 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- flex 分页
<?xml version="1.0" encoding="utf-8"?><s:Group xmlns:fx="http://ns ...