SQL Server 的事务和锁(一)

 

最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT @findCount=COUNT(id) FROM MyTable
WHERE [fk_related_id]=@Argument
 
IF (@findCount > 0)
BEGIN
    ROLLBACK TRANSACTION
    RETURN ERROR_CODE
END
 
INSERT INTO MyTable ([fk_related_id],…)
VALUES (@Argument,…)
 
COMMIT TRANSACTION
RETURN SUCCESS_CODE

在搞清楚这个问题的过程中做了不少的实验,与各位共享。这一篇是开篇,主要说明的是 SQL Server 的四种(其实还有别的)经典的事务隔离级别,以及在不同的隔离级别下锁的使用手段,以及所带来的不同的数据一致性。

SQL Server 中锁的种类(Schema操作就暂时不涉及了)

锁类型 描述
(Shared Lock) 用于只读操作数据锁定
(Update Lock) 用于数据的更新,在数据真正的需要更新的时候会申请升级为X锁。
X(Exclusive Lock) 独占锁,用于数据的更改。
Key-Range Lock(稍后讨论) 仅仅在 Serializable 隔离级别保护数据,以避免任何有可能使得本事务第二次读取信息产生错误的数据插入操作

各个事务隔离级别下锁的使用

SQL Server 中有四种事务隔离级别,具体的大家去参建 MSDN。下面列出在不同的事务隔离级别下这些锁是如何使用的:

隔离级别 读数据锁状态 写数据锁状态 锁持有时间
Read Uncommitted 不获得任何锁 不获得任何锁  
Read Committed 数据获得S锁 对于 INSERT、DELETE、UPDATE的执行,获得X锁;对于UPDATE的标记,获得U锁; 读完即释放,并不持有至事务结束。
Repeatable Read 数据获得S锁 对于 INSERT、DELETE、UPDATE的执行,获得X锁;对于UPDATE的标记,获得U锁; 持有至事务结束
Serializable 数据获得S锁,同时获得Key-Range锁。 对于 INSERT、DELETE、UPDATE的执行,获得X锁;对于UPDATE的标记,获得U锁,同时获得Key-Range锁。 持有至事务结束

我们可以利用这些知识形象说明各个隔离级别下的数据一致性:

Read Uncommitted 级别

(1)脏读

(2)更新丢失

(3)不可重复读

(4)幻读

Read Committed 级别

(1)脏读

(2)更新丢失

(3)不可重复读

(4)幻读

Repeatable Read 级别

(1)脏读

(2)更新丢失

(3)不可重复读

(4)幻读

Serializable 级别

(1)脏读

(2)更新丢失

(3)不可重复读

(4)幻读

我们从上图可以比较直观的看到以下的结论

  脏读 更新丢失 不可重复读 幻读
Read Uncommitted 可能 可能 可能 可能
Read Committed 不可能 可能 可能 可能
Repeatable Read 不可能 不可能 不可能 可能
Serializable 不可能 不可能 不可能 不可能

这一篇到此为止,下一篇详细介绍 Key-Range Lock 并分析开篇提到的死锁问题。

(转)SQL Server 的事务和锁(一)的更多相关文章

  1. SQL Server 的事务和锁(一)

    最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 SELECT @ ...

  2. (转)SQL Server 的事务和锁(二)-Range S-S锁

    在这篇随笔中,我们的主要关注点在 Key-Range Lock.Key-Range Lock有 S-S.S-U.I-N.X-X几种情况.我们一个一个来说,力求明白.遗憾的是,这里可能会比较冗长,那么死 ...

  3. SQL Server 的事务和锁(二)-Range S-S锁

    在这篇随笔中,我们的主要关注点在 Key-Range Lock.Key-Range Lock有 S-S.S-U.I-N.X-X几种情况.我们一个一个来说,力求明白.遗憾的是,这里可能会比较冗长,那么死 ...

  4. SQL Server :事务和锁

    1.事务 事务概念:全部执行或全部不执行的一条或者多条语句的组合 例子说明:到银行里转账,将一个账户(Tom)里的100元钱转到另一个账户(Jake) update table money=money ...

  5. SQL Server 的事务和锁 图解

    http://www.cnblogs.com/lxconan/archive/2011/10/20/2218396.html

  6. SQL Server中事务、锁定和阻塞

    事务是什么 在SQL Server中事务是构成一个工作逻辑单元的一系列任务,也就说多个任务放在一起执行,这些任务要么全部执行成功,要么全部执行失败. 通过事务我们可以保证数据的完整性,例如:用户A给用 ...

  7. SQL Server里的闩锁介绍

    在今天的文章里我想谈下SQL Server使用的更高级的,轻量级的同步对象:闩锁(Latch).闩锁是SQL Server存储引擎使用轻量级同步对象,用来保护多线程访问内存内结构.文章的第1部分我会介 ...

  8. 如何读懂SQL Server的事务日志

    简介 本文将介绍SQL Server的事务日志中记录了哪一些信息,如何来读懂这些事务日志中信息.首先介绍一个微软没有公开的函数fn_dblog,在文章的接下来的部分主要用到这个函数来读取事务日志. f ...

  9. SQL Server Insert操作中的锁

    原文:SQL Server Insert操作中的锁 这篇博文简单介绍一下在SQL Server中一条Insert语句中用到的锁. 准备数据 首先我们建立一张表Table_1,它有两列Id(bigint ...

随机推荐

  1. BZOJ-1876 SuperGCD Python(欧几里德算法)

    第一次感觉Python艹题的快感 1876: [SDOI2009]SuperGCD Time Limit: 4 Sec Memory Limit: 64 MB Submit: 2461 Solved: ...

  2. BZOJ-2049 Cave洞穴勘测 动态树Link-Cut-Tree (并查集骗分TAT)

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 5833 Solved: 2666 [Submit] ...

  3. .net 代码风格规范

    声明:内容非原创,转自张子阳博客. 对于为什么是转载,唯一原因就是这东西居然比我整理的好,直接用得了. 1. C# 代码风格要求 1.1注释 类型.属性.事件.方法.方法参数,根据需要添加注释. 如果 ...

  4. Codeforces 578B "Or" Game

    传送门 B. "Or" Game time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  5. 初识A*算法

    写这篇文章的初衷是应一个网友的要求,当然我也发现现在有关人工智能的中文站点实在太少,我在这里抛砖引玉,希望大家都来热心的参与. 还是说正题,我先拿A*算法开刀,是因为A*在游戏中有它很典型的用法,是人 ...

  6. 使用.NET FrameWork获取CPU,内存使用率以及磁盘空间

    在以前,我们想获取CPU,内存等信息就不得不借助win32 API来实现.但现在,.NET FrameWork已经把这些API封装到.NET类库中了,所以我们可以借助.NET类库很轻松的获取这些信息. ...

  7. GIT本地操作

    01. GIT简介(PPT) ================================================================================ 02. ...

  8. 如何使用网盘托管git项目

    话说近年来git已经成为项目源代码管理的标准工具,有不少免费托管网站可供使用,详情参考这篇文章: http://www.cnblogs.com/zdz8207/archive/2012/05/20/2 ...

  9. WPF PopupNonTopmost重写

    之前做WPF遇到问题,在网上找到的一个类 public class PopupNonTopmost : System.Windows.Controls.Primitives.Popup { publi ...

  10. java本地方法如何调用其他程序函数,方法详解

    JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java 1.1 开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许J ...