Повторяемое чтение - правильно ли я понимаю? - PullRequest
10 голосов
/ 14 января 2010

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

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

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

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

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

Ответы [ 2 ]

19 голосов
/ 14 января 2010

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
2 голосов
/ 14 января 2010

Correct.

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

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

Общие блокировки размещаются на всех данных читать каждое утверждение в сделки и проводятся до транзакция завершена. Это мешает другие транзакции от изменения любого строки, которые были прочитаны текущая транзакция. Другой транзакции могут вставлять новые строки, которые соответствовать условиям поиска заявления, выданные действующим сделка. Если текущий транзакция затем повторяет утверждение он получит новые строки, которые приводит к фантомному чтению. Так как общие блокировки удерживаются до конца транзакция вместо того, чтобы быть выпущенным в конце каждого утверждения, параллелизм ниже, чем по умолчанию ЧИТАЙТЕ ЗАВЕРШЕННЫЙ уровень изоляции. использование эта опция только при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...