Как выбрать только те строки, которые были зафиксированы - sql2008 - PullRequest
1 голос
/ 06 сентября 2010

Как выбрать все строки для таблицы, они не являются частью транзакции, которая еще не зафиксирована?

Пример: Допустим,

Таблица T имеет 10 строк.

Пользователь A выполняет транзакцию с некоторыми запросами:

INSERT INTO T (...)
SELECT ...
FROM T

// doing other queries 

Теперь, вот сложная часть:

Что, если пользователь B в промежуток времени между пользователем A вставил строку и транзакция был зафиксирован, обновлял список в системе с помощью выбора в таблице T.

Я только хочу, чтобы пользователь SELECT B использовал возвращенные 10 строк (все строки из таблицы, которые позже не могут быть отменены). Как мне это сделать, если это вообще возможно?

Я попытался установить уровень изоляции для транзакции и добавить «WITH (NOLOCK)» «WITH (READUNCOMMITTED)» к запросу без какой-либо удачи.

Запрос либо возвращает все 11 записей, либо ожидает фиксации транзакции, и это не то, что мне нужно.

Любые советы очень ценятся, спасибо.

Ответы [ 3 ]

2 голосов
/ 06 сентября 2010

Необходимо использовать (по умолчанию) 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)
2 голосов
/ 06 сентября 2010

Изоляция снимка ?

Либо я, либо еще три человека, которые ответили рано, неправильно прочитали / неверно истолковали ваш вопрос, поэтому я дал ссылку, чтобы вы могли определить сами.

1 голос
/ 06 сентября 2010

На самом деле, read uncommitted и nolock одинаковы. Они означают, что вы видите строки, которые еще не были зафиксированы.

Если вы работаете на уровне изоляции по умолчанию, read committed, вы не увидите новые строки, которые не были зафиксированы. Это должно работать по умолчанию, но если вы хотите быть уверенным, префикс вашего выбора с set transaction isolation level read committed.

...