Повторяемое чтение - правильно ли я это понимаю?
Попытка полностью понять уровни изоляции SQL Server-в частности, повторяемое чтение.
У меня есть sproc, который запускает транзакцию и помещает курсор вокруг некоторых данных (boo hiss). Это может быть довольно большой объем данных, поэтому может занять некоторое время.
Затем он зафиксирует или откатит.
В течение этого времени, до закрытия транзакции, если кто-то вызывает метод, который заставляет некоторые из этих затронутых строк быть прочитанными, я понимаю, что этот метод остановится пока первый метод не будет завершен. Затем им будут переданы данные (до тех пор, пока тайм-аут не наступит первым)
Я думаю, что я прав, но вопрос в том-прав ли я?!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:
Указывает, что операторы не могут читать данные, которые были изменены, но не были изменены. еще не зафиксированы другой транзакцией и что никакие другие сделки не могут изменить данные, которые были прочитаны пользователем. текущей транзакции до тех пор, пока текущая транзакция завершена.
Общие блокировки размещаются на всех данных прочтите каждое утверждение в сделки и проводятся до тех пор, пока транзакция завершена. Этот препятствовать другие транзакции от изменения любых строки, которые были прочитаны текущая транзакция. Другой транзакции могут вставлять новые строки, которые соответствуют условиям поиска: заявления, опубликованные нынешним торговая операция. Если текущий транзакция затем повторяет инструкцию он будет извлекать новые строки, которые приводит к фантомным считываниям. Потому что общий блокировки удерживаются до конца вместо того, чтобы сделки были освобождены в конце каждого утверждения, параллелизм-это ниже, чем по умолчанию Прочитайте уровень изоляции фиксации. Воспользуйся этот вариант возможен только в случае необходимости.