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


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

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

Затем он зафиксирует или откатит.

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

Я думаю, что я прав, но вопрос в том-прав ли я?!
2 10

2 ответа:

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's not compatible with the shared lock. Locks
1 SELECT -- the lock is already placed. Succeeds.

Обновление:

Что касается вашего вопроса: в 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

Правильно.

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

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

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