摘自:http://www.cnblogs.com/haiyang1985/archive/2009/02/27/1399641.html

锁机制

NOLOCK和READPAST的区别。

1.       开启一个事务执行插入数据的操作。

BEGIN TRAN t

INSERT INTO Customer

SELECT 'a','a'

2.       执行一条查询语句。

SELECT * FROM Customer WITH (NOLOCK)

结果中显示”a”和”a”。当1中事务回滚后,那么a将成为脏数据。(注:1中的事务未提交) 。NOLOCK表明没有对数据表添加共享锁以阻止其它事务对数据表数据的修改。

SELECT * FROM Customer

这条语句将一直死锁,直到排他锁解除或者锁超时为止。(注:设置锁超时SET LOCK_TIMEOUT 1800)

SELECT * FROM Customer WITH (READPAST)

这条语句将显示a未提交前的状态,但不锁定整个表。这个提示指明数据库引擎返回结果时忽略加锁的行或数据页。

3.       执行一条插入语句。

BEGIN TRAN t

INSERT INTO Customer

SELECT 'b','b'

COMMIT TRAN t

这个时候,即使步骤1的事务回滚,那么a这条数据将丢失,而b继续插入数据库中。

NOLOCK

1. 执行如下语句。

BEGIN TRAN ttt

SELECT * FROM Customer WITH (NOLOCK)

WAITFOR delay '00:00:20'

COMMIT TRAN ttt

注:NOLOCK不加任何锁,可以增删查改而不锁定。

INSERT INTO Customer SELECT 'a','b' –不锁定

DELETE Customer where ID=1 –不锁定

SELECT * FROM Customer –不锁定

UPDATE Customer SET Title='aa' WHERE ID=1 –不锁定

ROWLOCK

1.       执行一条带行锁的查询语句。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ -- (必须)

BEGIN TRAN ttt

SELECT * FROM Customer WITH (ROWLOCK) WHERE ID=17

WAITFOR delay '00:00:20'

COMMIT TRAN ttt

注:在删除和更新正在查询的数据时,会锁定数据。对其他未查询的行和增加,查询数据无影响。

INSERT INTO Customer SELECT 'a','b' –不等待

DELETE Customer where ID=17 –等待

DELETE Customer where ID<>17 –不等待

SELECT * FROM Customer –不等待

UPDATE Customer SET Title='aa' WHERE ID=17–等待

UPDATE Customer SET Title='aa' WHERE ID<>17–不等待

HOLDLOCK,TABLOCK和TABLOCKX

1.       执行HOLDLOCK

BEGIN TRAN ttt

SELECT * FROM Customer WITH (HOLDLOCK)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

注:其他事务可以读取表,但不能更新删除

update Customer set Title='aa' —要等待10秒中。

SELECT * FROM Customer —不需要等待

2.       执行TABLOCKX

BEGIN TRAN ttt

SELECT * FROM Customer WITH (TABLOCKX)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

注:其他事务不能读取表,更新和删除

update Customer set Title='aa' —要等待10秒中。

SELECT * FROM Customer —要等待10秒中。

3. 执行TABLOCK

BEGIN TRAN ttt

SELECT * FROM Customer WITH (TABLOCK)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

注:其他事务可以读取表,但不能更新删除

update Customer set Title='aa' —要等待10秒中。

SELECT * FROM Customer —不需要等待

UDPLOCK

1.       在A连接中执行。

BEGIN TRAN ttt

SELECT * FROM Customer WITH (UPDLOCK)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

2.       在其他连接中执行。

update Customer set Title='aa' where ID=1—要等10秒

SELECT * FROM Customer –不用等

insert into Customer select 'a','b'–不用等

注:对于UDPLOCK锁,只对更新数据锁定。

注:使用这些选项将使系统忽略原先在SET语句设定的事务隔离级别(SET Transaction Isolation Level)。

事务隔离级别

脏读:READ UNCOMMITTED

脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

1.       在A连接中执行。

BEGIN TRAN t

INSERT INTO Customer

SELECT '123','123'

WAITFOR delay '00:00:20'

COMMIT TRAN t

2.       在B连接中执行。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT * FROM Customer

这个时候,未提交的数据会’123’会显示出来,当A事务回滚时就导致了脏数据。相当于(NOLOCK)

提交读:READ COMMITTED

1.       在A连接中执行。

BEGIN TRAN t

INSERT INTO Customer

SELECT '123','123'

WAITFOR delay '00:00:20'

COMMIT TRAN t

2.       在B连接中执行。

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT * FROM Customer

这个时候,未提交的数据会’123’不会显示出来,当A事务提交以后B中才能读取到数据。避免了脏读。

不可重复读:REPEATABLE READ

不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

例如:

1.       在A连接中执行如下语句。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRAN ttt

SELECT * FROM Customer WHERE ID=17

WAITFOR delay '00:00:30'

SELECT * FROM Customer WHERE ID=17

COMMIT TRAN ttt

2.       在B连接中执行如下语句,而且要在第一个事物的三十秒等待内。

UPDATE Customer SET Title='d' WHERE ID=17

这个时候,此连接将锁住不能执行,一直等到A连接结束为止。而且A连接中两次读取到的数据相同,不受B连接干扰。

注,对于Read Committed和Read UnCommitted情况下,B连接不会锁住,等到A连接执行完以后,两条查询语句结果不同,即第二条查询的Title变成了d。

序列化读:SERIALIZABLE

1.       在A连接中执行。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN t

UPDATE Customer SET Title='111'

WAITFOR delay '00:00:20'

COMMIT TRAN t

2. 在B连接中执行,并且要在A执行后的20秒内。

BEGIN TRAN tt

INSERT INTO Customer

SELECT '2','2'

COMMIT TRAN tt

在A连接的事务提交之前,B连接无法插入数据到表中,这就避免了幻觉读。

注:幻觉读是指当事务不是独立执行时发生的一种现象,例如 第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。

共享锁

共享锁(S 锁)允许并发事务在封闭式并发控制(请参阅并发控制的类型)下读取 (SELECT) 资源。资源上存在共享锁(S 锁)时,任何其他事务都不能修改数据。读取操作一完成,就立即释放资源上的共享锁(S 锁),除非将事务隔离级别设置为可重复读或更高级别,或者在事务持续时间内用锁定提示保留共享锁(S 锁)。

更新锁

更新锁(U 锁)可以防止常见的死锁。在可重复读或可序列化事务中,此事务读取数据 [获取资源(页或行)的共享锁(S 锁)],然后修改数据 [此操作要求锁转换为排他锁(X 锁)]。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排他锁(X 锁)。共享模式到排他锁的转换必须等待一段时间,因为一个事务的排他锁与其他事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排他锁(X 锁)以进行更新。由于两个事务都要转换为排他锁(X 锁),并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。

若要避免这种潜在的死锁问题,请使用更新锁(U 锁)。一次只有一个事务可以获得资源的更新锁(U 锁)。如果事务修改资源,则更新锁(U 锁)转换为排他锁(X 锁)。

排他锁

排他锁(X 锁)可以防止并发事务对资源进行访问。使用排他锁(X 锁)时,任何其他事务都无法修改数据;仅在使用 NOLOCK 提示或未提交读隔离级别时才会进行读取操作。

数据修改语句(如 INSERT、UPDATE 和 DELETE)合并了修改和读取操作。语句在执行所需的修改操作之前首先执行读取操作以获取数据。因此,数据修改语句通常请求共享锁和排他锁。例如,UPDATE 语句可能根据与一个表的联接修改另一个表中的行。在此情况下,除了请求更新行上的排他锁之外,UPDATE 语句还将请求在联接表中读取的行上的共享锁。

转载于:https://www.cnblogs.com/GaoAnLee/p/7041243.html

SQL锁机制和事务隔离级别相关推荐

  1. 小米id锁状态查询_MySQL锁机制与事务隔离级别

    01 什么是事务? 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性. 原子性(Atomicity) :事务是一个原子操作单元,其对数据的修改,要么全都执行 ...

  2. 一文讲清,MySQL事务隔离级别

    业务系统在运行的时候,往往有很多线程同时在操作数据库,MySQL也需要多线程的处理多个请求,那么每个事务里的多个SQL语句是如何执行的呢? 基本都是从磁盘加载数据页到Buffer Pool的缓存页里去 ...

  3. SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)

    五.锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误.设置事务隔离级别将影响整条连接. ...

  4. spring事务隔离级别与数据库事务隔离级别的关系

    一直没搞清楚spring事务与数据库事务与锁之间的关系. spring事务: spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spri ...

  5. mysql 事务隔离级别实现原理_MySQL事务隔离级别和实现原理 - 米扑博客

    开发中经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗, 事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢? MySQL 事务 本文所说的 MySQL 事务都是指在 InnoDB 引 ...

  6. java 一个大事务下的新增、修改、查询_重新学习Mysql数据库8:MySQL的事务隔离级别实战...

    本文转自:https://blog.csdn.net/sinat_27143551/article/details/80876127 本系列文章将整理到我在GitHub上的<Java面试指南&g ...

  7. 概述MySQL数据库---事务隔离级别

    同一个应用程序中的多个事务或不同应用程序中的多个事务在同一个数据集上并发执行时, 可能会出现许多意外的问题,事务并发处理可能引起的问题可分为如下三种类型: 脏读(Drity Read): 已知有两个事 ...

  8. SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)

    六.各种事务隔离级别发生的影响 修改数据的用户会影响同时读取或修改相同数据的其他用户.即这些用户可以并发访问数据.如果数据存储系统没有并发控制,则用户可能会看到以下负面影响: · 未提交的依赖关系(脏 ...

  9. MySQL深度剖析之事务隔离级别和锁机制(2021)

    一 事务隔离级别和锁机制 1.1 多个事务并发修改同一条数据或者对同一条数据并发读写存在哪些事务并发问题 1.1.1 脏读(未提交读) A事务读取了别的事务还未提交的更新,而B事务是有可能回滚的. 1 ...

最新文章

  1. 1322项!这所高校国自然基金立项再创新高 | 附各高校最新统计
  2. css中overflow:hidden的属性 可能会导致js下拉菜单无法显示
  3. git 的右键快捷菜单恢复
  4. git 命令行使用(基础篇)
  5. Linux之服务器时间同步
  6. php 语句,php的控制语句
  7. 带有Java DSL的Spring Integration MongoDB适配器
  8. csp-c模拟测试43「A·B·C」
  9. 《电路分析导论(原书第12版)》一1.2.2 真空电子时代
  10. raw转bmp程序c语言,求指导,如何用c语言实现读取*.raw格式图像
  11. 苹果手机键盘html代码大全,iPhone拨号键盘中的*和#有什么作用 iPhone特殊代码分享...
  12. 面包板入门制作之三极管详解
  13. php 输入经纬度查询位置,PHP根据一个给定经纬度的点,进行附近地点查询
  14. 微信公众号网页分享功能开发
  15. 英文版xp系统下载ghost xp sp3英文版(双语纯净版、可随意转换)
  16. 微信小程序-书籍阅读 【阅读、小说阅读、图书、世界读书日、爱读书爱分享】
  17. 苹果 CMS 搭建视频网站,定时采集视频
  18. 【语音增强论文解读 02】DCCRN: Deep Complex Convolution Recurrent Network for Phase-AwareSpeech Enhancement
  19. 推荐一款开源的音乐下载神器,8个平台VIP任你选
  20. torch 移植 Mindspore 历程(未完成)

热门文章

  1. Java普通工程转换成标准的maven工程
  2. 设置 ASP.NET 存储当前应用程序的临时文件(生成的源、编译了的程序集等)的目录的物理路径。...
  3. LeetCode 5380. 数组中的字符串匹配
  4. 刷题笔记(1) 一个序列是否为二叉搜索树的遍历结果
  5. Scikit-learn机器学习算法库代码实践
  6. 如何快速搭建yum源和成功检测第三方软件
  7. 7-5 输出字符串中出现的字符 (20 分)
  8. 宅家办公不宅心,送3本技术好书
  9. 2019 fall CS224w:01-intro
  10. TENSORFLOW 指定使用GPU跑