Я использую SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
в большинстве своих общих запросов SQL, главным образом потому, что это было подробно изучено при первоначальном изучении языка.
WITH (NO LOCK)
Насколько я понимаю, этот уровень изоляции действует так же, как и я, когда-либо склонен использовать SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.
- Есть ли когда - нибудь время, когда я должен использовать
WITH (NO LOCK)
болееSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
. - Не
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
мешает ли другим пользователям быть заблокированными из таблиц, которые я читаю? - Если
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
используется для остановки блокировок, но я только читаю данные, какой смысл в этом? Только системные запросы будут генерировать блокировки? Стоит ли использовать его при выполнении запросов, которые возвращаются, скажем, через 5-10 секунд? - Мне сказали не использовать
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
при чтении данных, которые будут использоваться в обновлениях, по-видимому, чтобы избежать обновления грязных данных. Будет ли это единственной причиной? - С типом базы данных, над которой я работаю, есть среда производства и тестирования. Мы очень редко будем запрашивать производственную среду, но когда мне нужно, я обычно буду использовать
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
в своем запросе. Я понимаю, что с этим возможно грязное чтение. Помимо получения данных обратно, которые могут не в конечном итоге быть переданы в базу данных (и, следовательно, выбросить мои результаты), какие другие типы «грязного чтения» могут быть возможны?
Извините за массу вопросов.
sql-server
isolation-level
dmoney
источник
источник
READ UNCOMMITTED
везде, точно так же, как я бы не использовалWITH (NOLOCK)
везде (по сути, это одно и то же) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhereОтветы:
Страшно, что ты так научился (извини!).
READ UNCOMMITTED
давайте читать каждую строку, да. Даже те , кто в настоящее время используется вINSERT
,UPDATE
,DELETE
операциях. Это очень полезно, если вам нужно быстро взглянуть на некоторые данные или критически важныеSELECT
условия, когда блок может быть очень вредным.На самом деле, вы рискуете своей честностью. Может случиться, что вы прочитаете строку, которая в данный момент используется для удаления или изменения. Также может показаться, что вы прочитали неправильное значение. Это может быть действительно необычным, но это может случиться. Что я имею в виду с этим? Хорошо, представьте себе строку, которая очень широка (в ней много столбцов и много длинных
nvarchar
столбцов). Обновление происходит в этой строке и устанавливает новые значения. В редких случаях с вами может случиться, что вы читаете только пол строки. Например, может произойти и другое, если пользователь изменит свои значения для входа. Он меняет свою почту + пароль. Почта уже установлена, но пароль - нет. Таким образом, у вас есть противоречивое состояние.Я бы предложил забыть о
READ UNCOMMITTED
. Просто используйте его там, где это действительно необходимо.Другой альтернативой для вас может быть включение
READ_COMMITTED_SNAPSHOT
опции базы данных - поэтому вы можете использовать ееREAD COMMITTED SNAPSHOT
из-за включенного управления версиями строк в вашей базе данных tempdb. Таким образом, вы просто читаете другую (более старую) версию строки. Это не заблокирует ваши запросы. Но может случиться так, что вы тоже прочитали старое значение, но непротиворечивое старое значение.Другая идея может быть
WITH(READPAST)
вместоWITH(NOLOCK)
. Вы прочитаете старое состояние таблицы (немного похоже наSNAPSHOT ISOLATION
), но вместо этого вы пропустите все заблокированные на данный момент строки.источник
SNAPSHOT ISOLATION
не нужно включать, чтобы включитьREAD COMMITTED SNAPSHOT
.READ COMMITTED SNAPSHOT
Необходимо включить только параметр базы данных, чтобы управление версиями строк вместо блокировок обеспечивало согласованность при чтении, избегая необходимости грязного чтения.Как говорится в принятом ответе, забудьте об использовании уровня изоляции READ UNCOMMITTED (за исключением случаев, когда это действительно необходимо), так как вы рискуете прочитать неверные данные. Но чтобы ответить на 3-й пункт в вашем вопросе, есть две ситуации, которые я считаю полезными:
При написании и тестировании пакетов служб SSIS SQL Server этапы пакета могут быть включены в транзакцию. Если вы тестируете пакет, выполняя его шаг за шагом в отладчике служб SSIS, вам может потребоваться проверить таблицы, пока в таблице есть блокировки. Использование команды SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED позволяет использовать SQL Server Manager Studio для проверки таблиц во время отладки пакета.
В SQL Server Manager Studio вы можете протестировать код T-SQL, заключив его в транзакцию, чтобы дать вам возможность откатить изменения. Например, в тестовой базе данных вы можете захотеть восстановить данные в исходное состояние как часть вашего теста. Если вы тестируете код в транзакции и хотите проверить заблокированные таблицы во время выполнения транзакции, вы можете использовать SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED, чтобы проверить значения в другом окне.
Я принимаю, что это довольно неясное использование READ UNCOMMITTED, но я нашел их полезными в тестовой среде.
источник
В большинстве баз данных подавляющее большинство операций, даже вставок, удалений и обновлений, находится вне явных транзакций.
Конечно,
READ UNCOMMITTED
(Грязные чтения) может предоставить неверную информацию в этих случаях, но эта информация была правильной 5 секунд раньше.Случаи, когда грязное чтение приводит к действительно плохим результатам, - это когда транзакция завершается неудачно и требует отката или когда выполняется запрос к двум таблицам, которые обычно обновляются вместе с использованием явной транзакции.
Между тем, в типичной большой, занятой базе данных, в которой отношение чтения к записи составляет 100 (или более) к 1, КАЖДЫЙ одиночный (чтение) запрос, который не использует грязное чтение, замедляет работу системы, поскольку ему необходимо получить и проверить для блокировок И это значительно повышает вероятность сбоя транзакций (обычно из-за тупиковых ситуаций), что может вызвать более серьезные проблемы с целостностью базы данных.
Вместо этого, использование грязного чтения делает систему НАМНОГО быстрее и надежнее (отчасти из-за улучшенной производительности, что снижает вероятность возникновения несоответствий).
Конечно, бывают случаи, когда их не следует использовать. Мне не нравится устанавливать для базы данных значение по умолчанию для использования
READ UNCOMMITTED
уровня изоляции или даже использовать явноеSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
выражение в начале сценариев SQL и SP - существует слишком большая вероятность того, что Dirty Read произойдет, когда этого не следует делать. Вместо этого(NOLOCK)
подсказки являются гораздо лучшим подходом, поскольку они явно указывают, что программист задумался о том, что они делают, и решили, что для этой конкретной таблицы в этом конкретном запросе «грязные чтения» были безопасными.Если вы программируете приложение для перевода денег с одного банковского счета на другой, вам не следует использовать Dirty Reads. Но большинству приложений такой уровень паранойи не нужен.
источник