NOLOCK和UNCOMMITTED有什么区别?

65

我使用SQL Server 2012。

我编写了两个查询,但是NOLOCKUnCommitted之间有什么区别?

SELECT lastname, firstname
FROM HR.Employees with (READUNCOMMITTED)

SELECT lastname, firstname 
FROM HR.Employees with (NoLock)

6
NOLOCK的文档说明:NOLOCK:等同于READUNCOMMITTED。我想这应该回答了你的问题。如果你想进一步了解,相关章节在Books Online 中的“表提示”中。 - jpw
@jpw 请给我一个链接。 - Ardalan Shahgholi
您可以通过按下 F1 键来访问文档,以获取有关此信息的详细信息:http://msdn.microsoft.com/zh-cn/library/ms187373(v=sql.110).aspx - jpw
@jpw:感谢F1。 - Ardalan Shahgholi
5个回答

65

NOLOCK:等同于READ UNCOMMITTED(来源:MSDN

NOLOCKREAD UNCOMMITTED指定允许脏读取。不会发出共享锁,以防止其他事务修改当前事务读取的数据,并且由其他事务设置的排他锁不会阻塞当前事务读取已锁定的数据。允许脏读可以提高并发性,但代价是读取随后被其他事务回滚的数据修改。

READ UNCOMMITTEDNOLOCK提示仅适用于数据锁定。所有查询(包括使用with READ UNCOMMITTED和NOLOCK提示的查询)在编译和执行期间都获取Sch-S(模式稳定性)锁。因此,当并发事务持有表的Sch-M(模式修改)锁时,查询将被阻止。


31

就像其他人提到的那样,它们在功能上没有区别。

唯一的区别是你可以有选择性地在某些表上应用WITH(NOLOCK),而在其他表上不应用。 READ UNCOMMITTED会在会话中的所有表上应用NOLOCK

如果您这样做:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT *
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.ID = T2.id

它在功能上等同于:

SELECT *
FROM Table1 T1 WITH(NOLOCK)
INNER JOIN Table2 T2 WITH(NOLOCK) ON T1.ID = T2.ID

但你也可以有选择地应用 WITH(NOLOCK)

SELECT *
FROM Table1 T1 WITH(TABLOCK)
INNER JOIN Table2 WITH(NOLOCK) ON T1.ID = T2.ID

3
顺便提一句,原帖是在询问同义词表提示 NOLOCK 和 READUNCOMMITTED。 - Lee Grissom

25

在实现上,它们执行的是相同的操作。

READ UNCOMMITTED 隔离级别是 SQL Server 中最不限制的隔离级别之一,这也是开发人员在寻求减少阻塞时流行的原因。

在后台,NOLOCK 表提示执行与运行在 read-uncommitted 隔离级别下完全相同的操作。

两者之间唯一的区别是:READ UNCOMMITTED 隔离级别确定整个连接的锁定机制,而 NOLOCK 表提示确定您提供提示的表的锁定机制。


10

在语句级别上没有区别。

你可以在会话级别设置READUNCOMMITTED,在这里你需要写 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


2

对于 NOLOCK ,我们需要在表级别上添加此提示,因此需要为每个在更新事务中使用的表级别添加。因此,在查询中引用的每个表都需要放置,这样非常冗长且耗时。对于 READ UNCOMMITTED ,我们不需要在每个表级别上放置它,只需在会话级别或查询级别上放置,并可以写在查询或存储过程的顶部。

让我们看一个小演示来说明它。首先在此检查数据库默认隔离级别

CREATE TABLE SAMPLETABLE
(
Col1 INT ,
Col2 VARCHAR(100)
)

INSERT INTO SAMPLETABLE(Col1,Col2)
SELECT 1,'Col1'
Union all
SELECT 2,'Col1'

BEGIN TRANSACTION 

Update SAMPLETABLE Set Col2 = 'Value changed' Where col1 =1

Select * from SAMPLETABLE with (nolock)



SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Select * from SAMPLETABLE 

输出结果是对于两个查询都是 1,Col1。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接