-
Коллеги!
Как сделать в ADODB следующее: хочу установить уровень изоляции на один конкретный SELECT, в частности, хочу, чтобы он выполнился под READ UNCOMMITED.
Проблема в том, что установка сабжа не дает нужный результат из-за: When setting the IsolationLevel property, this change does not take effect until the next time that the BeginTrans method is called. (это цитата из MSDN для сабжа).
Неужели единственная возможность явно ставить в батче SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED?
Спасибо!
ЗЫ Про указания в запросе вида with (NOLOCK) знаю. Но в моем конкретном случае - это крайний вариант, т.к. запросы автогенеренные.
-
в сообщении прямо написано, изменение действует не на текущую транзакцию, а следующую после после установки. и что? так многое работает, сначала установка желаемых параметров, после вызов метода объекта с этими параметрами. где проблема?
-
> где проблема?
Насколько я понимаю, уровень изоляции влияет не только на того, кто меняет, но и на того, кто читает.
В моем вопросе речь идет именно о читателе. Т.е. я хочу прочесть (select) грязные данные. Транзакцию я открывать явно не собираюсь.
Разве SET TRANSACTION ISOLATION LEVEL оказывает влияние только на явную транзакцию?
-
> хочу установить уровень изоляции на один конкретный SELECT
Уровень изоляции - это свойство транзакции. Оно определяет, как для одной транзакции видны изменения базы данных одновременно выполняемые другими транзакциями. Транзакции имеют возможность быть отмененными, соответственно, ты можешь получить состояние, которого никода не было в базе данных.
То, что ты хочешь, ведет к ошибкам и не надо тебе этого хотеть.
-
> Игорь Шевченко © (12.03.17 10:25) [3] > > хочу установить уровень изоляции на один конкретный SELECT > Уровень изоляции - это свойство транзакции.
Уровень изоляции - это свойство транзакции. Ты, конечно, прав.
Но в MSSQL server любой SELECT без явной транзакции, выполняется в рамках неявной транзакции. И на него установка Isol Level влияет.
"Практика - критерий истины", как говорил один мой коллега по цеху ;) Руководствуясь этим принципом я выяснил, что прав. Потом и доку в мсдн соответствующую нашел.
Т.е. утверждение такое (подкреплено и практикой и документацией) - Isol Level влияет на одиночный SELECT (без BEGIN TRAN).
Т.е. проблема именно в том, что ADODB.Connection выставляет Isol Level, только при явном начала транзакции. А при одиночном SELECT (который тоже идет в неявной транзакции, как выяснено ранее) не выставляет.
В этом у меня и есть вопрос к знатокам ADODB - как заставить проставить Isol Level без явного начала транзакции.
Крайний вариант - я в батч могу добавить SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED перед SELECT. Но это крайний вариант, наверняка д.б. более цивилизованный.
-
Используйте храниые процедуры и забудьте про дин. запросы. )
-
"В многопользовательской базе данных грязное чтение может быть опасным. В результате такого чтения не только выдается неверный результат, но могут выдаваться даннык, никогда не существовавшие в базе данных". (Том Кайт)
То, что ты хочешь, ведет к ошибкам и не надо тебе этого хотеть.
-
> То, что ты хочешь, ведет к ошибкам и не надо тебе этого > хотеть.
Напомнило цитату: Звёздные войны. Эпизод IV: Новая надежда: — Вам не надо проверять наши документы. Это не те дроиды, которых вы ищете. — Нам не надо проверять их документы. Это не те дроиды, которых мы ищем. Проезжай!:) Хорошо! Я согласен, это не тот уровень изоляции, который мне нужен. Хочу Serializable! Хочу, чтобы ADODB сгенерил такой код: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SELECT * FROM SomeTable
где TIL задается через ADODB.Connection.IsolationLevel, а не непосредственно в батче. Неужели нельзя?
-
А разве нельзя начать один раз длинную читающую транзакцию, а потом уже читать много раз?
-
> А разве нельзя начать один раз длинную читающую транзакцию, > а потом уже читать много раз?
Можно, но мне нужно прочесть под READ UNCOMMITED ровно один SELECT. Потом вренуться в READ COMMITED. ----- Итог такой. Нашел в stackoverflow полностью аналогичный вопрос. Ответа тоже не дали))) Делать буду так, раз ADO не позволяет иначе: AdoCnn.IsolationLevel := adXactReadUncommitted
AdoCnn.BeginTrans
AdoCmd.Exeсute
AdoCnn.Commit
AdoCnn.IsolationLevel := adXactReadCommitted
Итоговый батч будет такой:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED -- AdoCnn.BeginTrans
BEGIN TRAN -- AdoCnn.BeginTrans
SELECT * FROM SomeTable -- AdoCmd.Exeсute
COMMIT -- AdoCnn.Commit
Хотя, повторюсь, оборачивать SELECT в транзакцию не обязательно: один SELECT и так выполняется в транзакции (неявно). Всем спасибо за участие!
|