Повторяющееся чтение - я понимаю это право?

Попытка полностью понять уровни изоляции SQL Server - особенно REPEATABLE READ.

У меня есть sproc, который запускает транзакцию и помещает курсор вокруг некоторых данных (boo hiss). Это может быть справедливый кусок данных, поэтому может потребоваться некоторое время.

Затем будет COMMIT или ROLLBACK.

В течение этого времени, до того, как транзакция была закрыта, если кто-то вызывает метод, который вызывает некоторые из этих затронутых строк, READ, я понимаю, что этот метод остановится до тех пор, пока первый метод не будет завершен. Затем они будут обслуживаться данными (если тайм-аут не возникает раньше)

Я думаю, что я прав, но вопрос в том, что я?

Ответ 1

REPEATABLE READ предотвращает SELECTs от удаления общих блокировок, которые они размещают до конца транзакции.

С транзакцией 1 как READ COMMITTED вы можете обновить строку в транзакции 2 после ее выбора в транзакции 1.

С транзакцией 1 как REPEATABLE READ вы не можете обновить строку в транзакции 2 после ее выбора в транзакции 1.

Сценарии:

ПРОВЕРИТЬ КОМИТЕТ

1 SELECT -- places a shared lock and immediately lifts it.
2 UPDATE -- places an exclusive lock. Succeeds.
1 SELECT -- tries to place a shared lock but it conflicts with the exclusive lock placed by 2. Locks.

ПОВТОРНОЕ ПРОЧИТАНИЕ

1 SELECT -- places a shared lock and keeps it
2 UPDATE -- tries to places an exclusive lock but it not compatible with the shared lock. Locks
1 SELECT -- the lock is already placed. Succeeds.

Update:

Что касается вопроса: в SQL Server, SELECTs не будет блокировать друг друга даже с помощью REPEATABLE READ, так как общие блокировки, которые они размещают, совместимы друг с другом:

CREATE TABLE t_lock (id INT NOT NULL PRIMARY KEY, value INT NOT NULL)
INSERT
INTO    t_lock
VALUES (1, 1)

-- Session 1

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 2

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 1

DEALLOCATE cr_lock
COMMIT

-- Session 2

DEALLOCATE cr_lock
COMMIT

Ответ 2

Правильно.

Полное описание из MSDN:

Указывает, что операторы не могут читать данные, которые были изменены, но не но совершены другими транзакциями и что никакие другие транзакции не могут изменять данные, которые были прочитаны текущей транзакции до текущей транзакция завершена.

Общие блокировки размещаются на всех данных читать каждое выражение в транзакции и удерживаются до тех пор, пока транзакция завершена. Это предотвращает другие транзакции от изменения любого строки, которые были прочитаны текущая транзакция. Другие транзакции могут вставлять новые строки, которые соответствуют условиям поиска заявления, выданные сделка. Если текущий транзакция затем повторяет выражение он будет извлекать новые строки, которые результаты в phantom читаются. Потому как общие блокировки сохраняются до конца транзакция вместо того, чтобы быть выпущенной в конце каждого заявления, concurrency ниже, чем значение по умолчанию READ COMMITTED уровень изоляции. использование этот параметр только при необходимости.