SQL Server - какой уровень изоляции для неблокирующих операторов выбора?

9

У меня есть длительная транзакция (называемая, скажем, T1), которая выполняет некоторые операции удаления, обновления и вставки в таблицу в SQL Server 2008 R2. В то же время другой процесс периодически запускает операторы выбора из этой таблицы.

При настройках изоляции по умолчанию (ЧИТАТЬ, ЧТО ЯВЛЯЕТСЯ?) T1 блокирует выполнение любых операторов выбора до тех пор, пока транзакция не завершится или не будет отменена.

Я хотел бы, чтобы операторы select работали с согласованными данными, даже когда транзакция еще не завершена. Я верю, что изоляция SNAPSHOT может помочь, но я не уверен, что я иду в правильном направлении. Будет ли это лучший уровень изоляции для этого приложения?

Во-вторых, я не имею никакого контроля над процессом, который вызывает операторы select, но у меня есть контроль над приложением .NET, которое вызывает T1. Будут ли необходимы какие-либо изменения уровня изоляции как для операторов выбора, так и для T1, или будет достаточно отметить только T1 как имеющий другой уровень изоляции?

growse
источник

Ответы:

8

В идеальном мире у вас есть два варианта: SNAPSHOT и READ COMMITTED SNAPSHOT (RCSI). Убедитесь, что вы понимаете основы уровней изоляции транзакций, прежде чем решить, что подходит для вашей рабочей нагрузки. Особенно следует помнить о различных результатах, которые вы можете увидеть в результате перехода на RCSI.

Похоже, это не идеальный мир, так как вы не можете контролировать приложение, которое генерирует операторы select. В этом случае единственный вариант - включить RCSI для рассматриваемой базы данных, чтобы при выборе автоматически использовался RCSI вместо READ COMMITTED.

Марк Стори-Смит
источник
6

Правильно, используйте изоляцию SNAPSHOT, чтобы получить согласованные, зафиксированные данные до начала транзакции.

READ UNCOMMITTED изоляция (иначе подсказка NOLOCK) будет читать грязные, противоречивые данные

Когда вы включаете изоляцию SNAPSHOT, она вступает в силу для всех последующих SELECT. ALTER DATABASEВ этом случае вы работаете с READ_COMMITTED_SNAPSHOT

Изменить: добавлена ​​ссылка + цитата ALTER DATABASE (мой жирный)

Включает опцию Read-Committed Snapshot на уровне базы данных. Когда он включен, операторы DML начинают генерировать версии строк, даже если ни одна транзакция не использует изоляцию моментальных снимков. Как только эта опция включена, транзакции, указывающие уровень изоляции зафиксированного чтения, используют управление версиями строк вместо блокировки. Когда транзакция выполняется на уровне изоляции зафиксированного чтения, все операторы видят моментальный снимок данных в том виде, в каком они существуют в начале оператора.

И от использования Snapshot Isolation (мой жирный)

Параметр базы данных READ_COMMITTED_SNAPSHOT определяет поведение уровня изоляции READ COMMITTED по умолчанию, когда в базе данных включена изоляция моментальных снимков. Если вы не укажете явно READ_COMMITTED_SNAPSHOT ON, READ COMMITTED будет применен ко всем неявным транзакциям. Это приводит к тому же поведению, что и установка READ_COMMITTED_SNAPSHOT OFF (по умолчанию). Когда READ_COMMITTED_SNAPSHOT OFF действует, компонент Database Engine использует общие блокировки для обеспечения уровня изоляции по умолчанию. Если для параметра базы данных READ_COMMITTED_SNAPSHOT задано значение ON, ядро ​​базы данных по умолчанию использует управление версиями строк и изоляцию моментальных снимков вместо использования блокировок для защиты данных.

Так да.

Включение RCSI позволит чтениям получать согласованные данные и не будет блокироваться авторами, которые продолжат использовать Read Committed

ГБН
источник
4

Я бы посоветовал вам прочитать следующий вопрос и ответы на него: Проблемы с блокировкой базы данных? ,

Поиск правильного уровня изоляции для использования на уровне базы данных - это самое быстрое, что вы можете сделать прямо сейчас, чтобы помочь вам решить эту проблему, потому что сейчас трудно изменить все приложения, которые касаются базы данных, и изменить их код. Поскольку вы сказали: «У меня нет никакого контроля над процессом, который вызывает операторы select», самый быстрый ответ будет состоять в том, чтобы переключить db на уровень изоляции Read Committed Snapshot, чтобы вы не касались запросов на чтение. В противном случае вам потребуется использовать уровень изоляции Snapshot для сеансов, которые читают данные во время ваших крупных транзакций.

Подробнее о выборе правильного здесь: Выбор уровней изоляции на основе управления версиями строк .

Мэриан
источник