Конференция "Базы" » ADODB.Connection.IsolationLevel
 
  • Тимохов Дима © (11.03.17 20:56) [0]
    Коллеги!

    Как сделать в 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) знаю. Но в моем конкретном случае - это крайний вариант, т.к. запросы автогенеренные.
  • sniknik © (11.03.17 21:09) [1]
    в сообщении прямо написано, изменение действует не на текущую транзакцию, а следующую после после установки. и что? так многое работает, сначала установка желаемых параметров, после вызов метода объекта с этими параметрами. где проблема?
  • Тимохов Дима © (11.03.17 21:17) [2]

    > где проблема?


    Насколько я понимаю, уровень изоляции влияет не только на того, кто меняет, но и на того, кто читает.

    В моем вопросе речь идет именно о читателе. Т.е. я хочу прочесть (select) грязные данные. Транзакцию я открывать явно не собираюсь.

    Разве SET TRANSACTION ISOLATION LEVEL оказывает влияние только на явную транзакцию?
  • Игорь Шевченко © (12.03.17 10:25) [3]

    > хочу установить уровень изоляции на один конкретный SELECT


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

    То, что ты хочешь, ведет к ошибкам и не надо тебе этого хотеть.
  • Тимохов Дима © (12.03.17 15:05) [4]

    > Игорь Шевченко ©   (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. Но это крайний вариант, наверняка д.б. более цивилизованный.
  • ухты © (12.03.17 15:26) [5]
    Используйте храниые процедуры и забудьте про дин. запросы. )
  • Игорь Шевченко © (12.03.17 17:44) [6]
    "В многопользовательской базе данных грязное чтение может быть опасным. В результате такого чтения не только выдается неверный результат, но могут выдаваться даннык, никогда не существовавшие в базе данных".
    (Том Кайт)

    То, что ты хочешь, ведет к ошибкам и не надо тебе этого хотеть.
  • Тимохов Дима © (12.03.17 20:19) [7]

    > То, что ты хочешь, ведет к ошибкам и не надо тебе этого
    > хотеть.


    Напомнило цитату:

    Звёздные войны. Эпизод IV: Новая надежда:
    — Вам не надо проверять наши документы. Это не те дроиды, которых вы ищете.
    — Нам не надо проверять их документы. Это не те дроиды, которых мы ищем. Проезжай!


    :)

    Хорошо! Я согласен, это не тот уровень изоляции, который мне нужен. Хочу Serializable!

    Хочу, чтобы ADODB сгенерил такой код:

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    SELECT * FROM SomeTable



    где TIL задается через ADODB.Connection.IsolationLevel, а не непосредственно в батче. Неужели нельзя?
  • Inovet © (12.03.17 21:13) [8]
    А разве нельзя начать один раз длинную читающую транзакцию, а потом уже читать много раз?
  • Тимохов Дима © (12.03.17 21:19) [9]

    > А разве нельзя начать один раз длинную читающую транзакцию,
    >  а потом уже читать много раз?

    Можно, но мне нужно прочесть под 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 и так выполняется в транзакции (неявно).

    Всем спасибо за участие!
 
Конференция "Базы" » ADODB.Connection.IsolationLevel
Есть новые Нет новых   [118679   +72][b:0][p:0.001]