SQL锁机制和事务隔离级别
摘自: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 语句还将请求在联接表中读取的行上的共享锁。
SQL锁机制和事务隔离级别的更多相关文章
- MySQL锁问题,事务隔离级别
未完待续... 概述 这里专门指的是InnoDB存储引擎的锁问题和事务隔离级别. ========================================================= 锁 ...
- Sql Server中的事务隔离级别
数据库中的事物有ACID(原子性,一致性,隔离性,持久性)四个特性.其中隔离性是用来处理并发执行的事务之间的数据访问控制.SqlServer中提供了几种不同级别的隔离类型. 概念 Read UnCom ...
- sql标准支持了事务隔离级别
事务隔离级别 尽管数据库为用户提供了锁的DML操作方式,但直接使用锁管理是非常麻烦的,因此数据库为用户提供了自动锁机制.只要用户指定会话的事务隔离级别,数据库就会分析事务中的SQL语句,然后自动为事务 ...
- InnoDB锁问题 & DB事务隔离级别
<参考:http://www.cnblogs.com/jack204/archive/2012/06/09/2542940.html>InnoDB行锁实现方式InnoDB行锁是通过给索引上 ...
- mysql锁机制和事务隔离
mysql事务 1.InnoDB事务原理 事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态. 在数据库提交时,可以确保要么所有修 ...
- (转)SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)
五.锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误.设置事务隔离级别将影响整条连接. ...
- SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)
五.锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误.设置事务隔离级别将影响整条连接. ...
- SQL Server事务隔离级别
事务 定义 事务是作为单个逻辑工作单元执行的一系列操作. 一个逻辑工作单元必须有四个属性,称为原子性.一致性.隔离性和持久性 (ACID) 属性,只有这样才能成为一个事务. 一个事务可以包含多个操作. ...
- (转)SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)
六.各种事务隔离级别发生的影响 修改数据的用户会影响同时读取或修改相同数据的其他用户.即这些用户可以并发访问数据.如果数据存储系统没有并发控制,则用户可能会看到以下负面影响: · 未提交的依赖关系(脏 ...
随机推荐
- UI自动化--PageObjects(页面对象)
核心的核心:减少了重复代码的数量,减少变更涉及面:做到如果UI发生更改,则只需在一个位置应用此修复程序. PageObject:将页面作为一个对象,进行封装,包括元素定位,封装获取各元素.操作的方法: ...
- Saltstack之SSH
salt-minion也可以不安装通过在master安装salt-ssh 1,安装 yum -y install salt-ssh 2,配置salt的花名册 vim /etc/salt/roster ...
- 字符串匹配 扩展KMP BM&Sunday
复杂度都是O(n) 扩展1:BM算法 KMP的匹配是从模式串的开头开始匹配的,而1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹 ...
- ubuntu16.04下安装opencv3.1.0
1.安装依赖项 sudo apt--dev pkg-config libavcodec-dev libavformat-dev libswscale-dev 可选的 sudo apt--dev lib ...
- python2和python3的不同
1.性能 Py3.0运行 pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可 以取得很好的优化结果. Py3.1性能比Py2 ...
- 【紫书】Quadtrees UVA - 297 四叉树涂色
题意:前序遍历给出两个像素方块.求两个方块叠加后有几个黑色格子. 题解:每次读进来一个方块,就在二维数组上涂色.每次把白色涂黑就cnt++: 具体递归方法是以右上角坐标与边长为参数,每次通过几何规律往 ...
- Python:lambda表达式(匿名函数)
lambda表达式: 通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便. 在Python中 ...
- 疯狂java讲义 第三版 笔记
java7新加特性: 0B010101 二进制数 int c=0B0111_1111; 数值中使用下划线分隔 switch 支持String类型 字符串常量放在常量池 String s0 ...
- stress test - volume test
D:\wamp64\bin\mysql\mysql5.7.11\bin>mysqlslap --delimiter=";" --query=" INSERT I N ...
- 洛谷P4438 道路 [HNOI/AHOI2018] 树形dp
正解:树形dp 解题报告: 传送门! 昂首先看懂题目趴QwQ大概就是说有棵满二叉树,有n个叶子节点(乡村)和n-1个非叶子节点,然后这棵树的每个节点有三个属性abc,对每个非叶子节点可以从与子节点的两 ...