SQL Server Insert操作中的锁
这篇博文简单介绍一下在SQL Server中一条Insert语句中用到的锁。
准备数据
首先我们建立一张表Table_1,它有两列Id(bigint)和Value(varchar),其中Id建立了主键。
CREATE TABLE [dbo].[Table_2](
[Id] [bigint] NOT NULL,
[Value] [nchar](10) NULL,
CONSTRAINT [PK_Table_2] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
然后插入两条数据。
insert into dbo.table_2
(id, value)
values
(1, ''),
(2, '');
开始测试
我们知道,在Transaction中共享锁在查询语句结束就释放了,而排它锁则在Transaction提交才释放。我们可以利用它来执行一个Insert,不提交Transaction,然后去查看锁的状态。注意,本文中查询窗口配置的Transaction隔离级别是默认值READ COMMITTED。
首先执行以下SQL:
begin tran t1 insert into dbo.table_2
(id, value)
values
(3, '');
然后查看锁:
SELECT
resource_type,
request_mode,
resource_description,
request_session_id,
request_status,
resource_associated_entity_id,
DB_NAME(resource_database_id)as resource_database
FROM
sys.dm_tran_locks
WHERE
resource_type <> 'DATABASE'
ORDER BY
request_session_id;
执行结果如下:
- 第一个是意向排他锁。它表示这个数据页下存在排他锁(就是第三个排他锁),我们发现它的resource_associated_entity_id和第三个锁一样。那么,这个数据页就是存放这行数据的这个主键的。
- 第二个也是意向排他。它的resource_type是OBJECT,此对象可以是数据表、视图、存储过程、扩展存储过程或任何具有对象 ID 的对象。它的resource_associated_entity_id这一列其实是object_id, 用函数object_name(object_id)看一下发现结果是Table_2。那么它下面存在的排他锁指的也是第三个锁了。
- 第三个是排他锁。resou_description指的是插入数据主键的哈希值。
补充1
此时,我们在另外一个命令窗口中执行以下查询语句不会产生阻塞:
SELECT *
FROM dbo.Table_2
WHERE id=1;
但另一条却会产生阻塞:
SELECT *
FROM dbo.Table_2
WHERE id=3;
来看看第一条SQL产生的锁。由于共享锁会在查询结束立即释放,因此我们加一个HOLDLOCK,让它在事务结束再释放:
begin tran t2 SELECT *
FROM dbo.Table_2 WITH(HOLDLOCK)
WHERE id=1;
这是执行完以上语句锁的情况:
第二条SQL会产生阻塞,因此可以直接查询然后看锁的情况:
我们发现第9行的resource_description和第3行是相同的,这也说明了主键的锁只是锁住了某一个值而已。
补充2
这条SQL也会被Insert阻塞:
SELECT
value
FROM
dbo.Table_2
WHERE
value=''
而且查看当前的锁可以发现,Key被锁的值正是Insert语句的Key值。这里有两个疑问:1. 为什么没用到主键列,却产生了主键锁。2.为什么Insert的数据还未commit,这里却会产生这一行主键的锁。
答:1. 我们查看查询计划,可以看到这条语句是用了聚集索引扫描,至于为什么不是表扫描,请看这里。 2. 由于事务隔离级别默认是Read Committed,所以这里会对已插入但未提交的数据主键加一个共享锁。
SQL Server Insert操作中的锁的更多相关文章
- (转)SQL Server 的事务和锁(一)
SQL Server 的事务和锁(一) 最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁: 1 2 3 4 5 6 7 8 9 1 ...
- SQL Server里的闩锁介绍
在今天的文章里我想谈下SQL Server使用的更高级的,轻量级的同步对象:闩锁(Latch).闩锁是SQL Server存储引擎使用轻量级同步对象,用来保护多线程访问内存内结构.文章的第1部分我会介 ...
- SQL Server里的自旋锁介绍
在上一篇文章里我讨论了SQL Server里的闩锁.在文章的最后我给你简单介绍了下自旋锁(Spinlock).基于那个基础,今天我会继续讨论SQL Server中的自旋锁,还有给你展示下如何对它们进行 ...
- SQL Server里的闩锁耦合(Latch Coupling)
几年前,我写了篇关于闩锁和为什么SQL Server需要它们的文章.在今天的文章里,我想进一步谈下非缓存区闩锁(Non-Buffer Latches),还有在索引查找操作期间,SQL Server如何 ...
- (转)SQL Server 的事务和锁(二)-Range S-S锁
在这篇随笔中,我们的主要关注点在 Key-Range Lock.Key-Range Lock有 S-S.S-U.I-N.X-X几种情况.我们一个一个来说,力求明白.遗憾的是,这里可能会比较冗长,那么死 ...
- SQL Server 的事务和锁(二)-Range S-S锁
在这篇随笔中,我们的主要关注点在 Key-Range Lock.Key-Range Lock有 S-S.S-U.I-N.X-X几种情况.我们一个一个来说,力求明白.遗憾的是,这里可能会比较冗长,那么死 ...
- SQL Server 的事务和锁(一)
最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 SELECT @ ...
- SQL server 2005中的锁(1)
在之前的一片随笔中,简单的说了一下SQL Server中的隔离级别.而SQL Server的隔离级别是通过锁的机制来实现的.现在深入一下,谈谈SQL Server中的锁. 开始之前,先要定义一下前提: ...
- 记一次SQL Server Insert触发器编写过程
实现功能:新增特定类型的新闻时,自动追加特定的背景图片. 第一版(错误信息:不能在 'inserted' 表和 'deleted' 表中使用 text.ntext 或 image 列),代码如下: - ...
随机推荐
- 【ASP.NET Web API教程】2 创建各种Web API
原文 [ASP.NET Web API教程]2 创建各种Web API Chapter 2: Creating Web APIs第2章 创建各种Web API 本文引自:http://www.asp. ...
- 虚拟机安装中文Fedora14和C/C++IDE开发环境
虚拟机安装中文Fedora14和C/C++IDE开发环境 2010-12-05 00:15:58 标签:中文Fedora14 IDE 开发环境 C/C++ 原创作品,允许转载,转载时请务必以超链接形式 ...
- javascript 自己主动绑定JS callback 的方法函数
自己写的一个javascript 智能绑定callback 而且调用运行的函数.主要用于异步请求的 ajax中: <!DOCTYPE html> <html> <head ...
- Struts2通过自己定义拦截器实现登录之后跳转到原页面
这个功能对用户体验来说是非常重要的.实现起来事实上非常easy. 拦截器的代码例如以下: package go.derek.advice; import go.derek.entity.User; i ...
- MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据
看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...
- eclipse Maven plugin 配置
1. eclipse -> help -> marketpalce -> search 在输入框中输入Maven,回车. 在搜索结果列表中往下拉几个安装 Maven Integrat ...
- Swift - 解析JSON数据(内置NSJSONSerialization与第三方JSONKit)
一,使用自带的NSJSONSerialization 苹果从IOS5.0后推出了SDK自带的JSON解决方案NSJSONSerialization,这是一个非常好用的JSON生成和解析工具,效率也比其 ...
- MySQL中同一时候存在创建和上次更新时间戳字段解决方法浅析
在写这篇文章之前.明白我的MySQL版本号. mysql> SELECT VERSION(); +------------+ | VERSION() | +------------+ | 5.5 ...
- SharePoint场管理-PowerShell(二)
1. 合并Log文件 Merge-SPLogFile –Path E:\Logs\MergedLog.log –StartTime "1/19/2010" –Overwrite 2 ...
- Oracle heap 表的主键 dump 分析
1. 创建heap 表: create table t1 (id char(10) primary key,a1 char(10),a2 char(10),a3 char(10)); SQL> ...