我使用的是SQL Server 2012。
我写了两个查询,但NOLOCK
和UnCommitted
之间有什么不同?
SELECT lastname, firstname
FROM HR.Employees with (READUNCOMMITTED)
SELECT lastname, firstname
FROM HR.Employees with (NoLock)
答案 0 :(得分:35)
NOLOCK:相当于READUNCOMMITTED
(来源: MSDN )
NOLOCK
或READUNCOMMITTED
指定允许脏读。不会发出共享锁以防止其他事务修改当前事务读取的数据,并且其他事务设置的排它锁不会阻止当前事务读取锁定的数据。允许脏读可以导致更高的并发性,但代价是读取数据修改然后由其他事务回滚
READUNCOMMITTED
和NOLOCK
提示仅适用于数据锁。所有查询(包括with READUNCOMMITTED and NOLOCK hints
)在编译和执行期间都会获取Sch-S(模式稳定性)锁。因此,当并发事务在表
答案 1 :(得分:14)
在幕后,他们正在执行相同的操作。
read-uncommitted
隔离级别是SQL Server中限制最少的隔离级别,这也是开发人员在寻求减少阻塞时流行的原因。
幕后的nolock
表提示执行与在读取未提交的隔离级别下运行完全相同的操作。
两者之间的 唯一区别是read-uncommitted
隔离级别确定整个连接的锁定机制和nolock
表提示确定您提供提示的表的锁定机制。
答案 2 :(得分:13)
与其他人提到的一样,他们的职能没有区别。
唯一的区别是,您可以选择性地在某些表上应用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
:
{{1}}
答案 3 :(得分:7)
声明级别没有区别。
你可以在会话级别设置READUNCOMMITED,在这里你必须写 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
答案 4 :(得分:1)
对于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为两个查询