如何选择表的所有行,它们不属于尚未提交的任何事务?
实施例: 让我们说,
表T有10行。
用户A正在使用某些查询进行交易:
INSERT INTO T (...)
SELECT ...
FROM T
// doing other queries
现在,这里有一个棘手的部分:
如果用户A在用户A插入行并且提交了事务之间的时间内,用户B正在使用表T上的select更新系统中的列表。
我只希望SELECT用户B正在使用返回10行(表中的所有行,以后不能回滚)。如果可能的话,我该怎么做呢?
我已尝试在事务上设置isolationlevel并在查询中添加“WITH(NOLOCK)”“WITH(READUNCOMMITTED)”而没有任何运气。
查询要么返回所有11条记录,要么等待事务提交,这不是我需要的。
任何提示都很受欢迎,谢谢。
答案 0 :(得分:2)
您需要使用(默认)read committed
隔离级别和READPAST
提示来跳过因未提交而被锁定的行(而不是被阻止等待锁被释放)
这确实依赖于INSERT取出行锁。如果它取消了页面锁定,您将回到被阻止状态。示例如下
连接1
IF OBJECT_ID('test_readpast') IS NULL
BEGIN
CREATE TABLE test_readpast(i INT PRIMARY KEY CLUSTERED)
INSERT INTO test_readpast VALUES (1)
END
BEGIN TRAN
INSERT INTO test_readpast
WITH(ROWLOCK)
--WITH(PAGLOCK)
VALUES (2)
SELECT * FROM sys.dm_tran_locks WHERE request_session_id=@@SPID
WAITFOR DELAY '00:01';
ROLLBACK
连接2
SELECT i
FROM test_readpast WITH (readpast)
答案 1 :(得分:2)
无论是我还是早期回答的三个人都误读/误解了你的问题,所以我给出了一个链接,以便你自己确定。
答案 2 :(得分:1)
实际上,read uncommitted
和nolock
是相同的。它们意味着你可以看到尚未提交的行。
如果以默认隔离级别read committed
运行,则不会看到尚未提交的新行。这应该在默认情况下有效,但如果您想确定,请在选择前添加set transaction isolation level read committed
。