Condividi tramite


Излучая оптимизм

В обновлении ядра Kernel Rollup для версии 3.0 был впервые использован механизм Optimistic Concurrency Control (OCC), более подробно о механизме можно почитать в SQL Server 2005 Books Online

Строго говоря, в Kernel Rollup OCC был задействован только для источников данных форм, остальные области, порождающие запросы к базе данных, не оптимизированы. Для поддержки OCC (а именно для обработки версий записей), в Kernel Rollup появилось поле RecVersion.

 

С точки зрения Microsoft Dynamics Ax модель OCC, реализованная в 4.0 и частично (как описано выше) в Kernel Rollup, состоит из следующих областей:

  • Удаления (выключения) подсказок типа 'forupdate' в коде X++ (со стороны ядра).
  • При обновлении одного или нескольких столбцов строки происходит проверка статуса изменения значения со времени, когда значение было считано в транзакции. Если значение было изменено, возникает исключительная ситуация и ядро генерирует исключение (Exception:UpdateConflict)
  • X++ код изменен для обработки таких исключений в обработчике try-catch

OCC подразумевает оптимистический и пессимистический сценарии. Выдержка из SQL Server Books Online:

"In a database scenario, there are two types of concurrency control mechanisms:

  • Optimistic concurrency control
    Optimistic concurrency control works on the assumption that resource conflicts between multiple users are unlikely, and it permits transactions to execute without locking any resources. The resources are checked only when transactions are trying to change data. This determines whether any conflict has occurred (for example, by checking a version number). If a conflict occurs, the application must read the data and try the change again. Optimistic concurrency control is not provided with the product, but you can build it into your application manually by tracking database access.
  • Pessimistic concurrency control
    Pessimistic concurrency control locks resources as needed, for the duration of a transaction. SQL Server Mobile supports pessimistic concurrency control that locks resources as needed for the duration of a transaction."

Собственно, пессимистический сценарий очень уж напоминает работу Microsoft Dynamics Ax до Kernel Rollup.

 

В 4.0 возможны следующие параметры работы OCC:

  • Оптимистический для тех таблиц, где включен параметр

  • Оптимистический для всех таблиц

  • Пессимистический

Есть также возможность использования уровня изоляции READ UNCOMMITED для всех запросов на чтение.

Что в итоге? В зависимости от нужд, можно оптимизировать производительность работы с базой данных. И это классно!

 

Однако надо учесть, что для оптимальной работы версионности записей (помните о RecVersion?) и, соответственно, OCC в Microsoft SQL Server 2005 необходимо включить уровень изоляции Read Committed Snapshot Isolation (RCSI).

 

Сделать это можно следующим запросом:

ALTER DATABASE <база данных Microsoft Dynamics Ax>
SET READ_COMMITTED_SNAPSHOT ON;

 

По умолчанию, данный уровень выключен, поведение Microsoft SQL Server 2005 при выключенном режиме соответсвует предыдущим версиям. Однако, данный механизм работает и в режиме совместимости (т.е. при работе базы с типом 80 на Microsoft SQL Server 2005).

 

 

Часто задаваемый вопрос: "А поможет ли включение READ_COMMITED_SHAPSHOT для Microsoft Dynamics Ax 3.0"? Вообще-то, версия 3.0 не поддерживает Read Committed Snapshot Isolation (RCSI) в Microsoft SQL Server 2005.

 

В заключение. Если код написан неоптимально, транзакция длится часами, то, чтобы не оптимизировал и не предлагал вендор со стороны ядра - большого выигрыша не достичь. Пишите оптимальный код, следите за селективностью создаваемых индексов...

Comments

  • Anonymous
    July 25, 2006
    Не могли бы Вы объяснить в 2 словах суть происходящего??

    1. Вроде как версионность в общем случае подразумевает хранение версий записей, т.е. их много, а в статье речь идет, насколько я понял о хранении номера ОДНОЙ последней транзакции изменившей запись??
    Ссылка: http://ibase.ru/devinfo/mga.htm

    2. Вроде как уровень изоляции snapshot который необходимо включить не видит изменений после него, т.е. работает с теми транзакциями кот были на момент старта даже несмотря на то что они могли быть удалены??? Т.е. это уровень подходящий для отчетов а не для OLTP системы, разве нет??
    http://ibase.ru/devinfo/ibtrans.htm

    3. Есть также возможность использования уровня изоляции READ UNCOMMITED для всех запросов на чтение - Т.е. все запросы вместо реад коммитед будут читать реад анкомиттед ??? Но позвольте, там же один мусор??

    4. "Для поддержки OCC (а именно для обработки версий записей), в Kernel Rollup появилось поле RecVersion."
    Почему версионность не на уровне СУБД реализована а на уровне приложения??? Это же жуткие тормоза?!?! Или СУБД требует наличия этого поля для любых приложений??

    5.
    Цитата:
    Если код написан неоптимально, транзакция длится часами, то, чтобы не оптимизировал и не предлагал вендор со стороны ядра - большого выигрыша не достичь. Пишите оптимальный код, следите за селективностью создаваемых индексов...  

    Золотые слова!!

    PS: Заранее извиняюсь за дилетантсткие вопросы. Если можно - для бестолковых ответьте, а то я спать не буду спокойно..

    Вопрос был задан по ссылке на Вашу публикацию (http://axforum.info/forums/showthread.php?p=111054#post111054)
    recoilme@iq-soft.ru
  • Anonymous
    August 02, 2006
    Спасибо за ссылки на InterBase, но я никогда не имел дела с данной СУБД, поэтому сравнивать не берусь. Кстати в ссылках упоминается Snapshot, вы случайно не путаете Read Committed Snapshot Isolation (RCSI) и Snapshot Isolation? Второе не поддерживается в версии 4.0.

    Поскольку данная тема относительно Microsoft SQL была неоднократно описана, я приведу ссылку, где есть подробная презентация на эту тему: https://msdb.ru/Downloads/Docs/Events/Materials/Technet05/SQL2005_Speed.ppt
    Выдержка из описания RCSI:
    "Процессы чтения видят зафиксированные значения на момент выполнения инструкции:
    • Процессы записи не блокируют процессы чтения
    • Процессы чтения не блокируют процессы записи"
    Т.е. если в транзации меняется запись, то ее значение на момент начала транзакции сохраняется в снимке. Читать из снимка другие транзакции могут без блокирования.

    RCSI изменяет поведение при чтении, но не при обновлении. Никаких проблем с целостностью нет, исключение описано ниже.  Также следующая ссылка может быть полезной: http://msdn2.microsoft.com/en-us/library/ms189050.aspx

    При установке Microsoft Dynamics Ax 4.0 инсталлятор создает базу данных с включенным алгоритмом RCSI.

    По сути, Dynamics Ax 4.0 использует RCSI Microsoft SQL 2005, поле RecVersion было введено для управления исключениями как надстройка на RCSI. Общий алгоритм выглядит следующим образом:
    - При считывании записи ВНУТРИ транзакции, считывается номер версии из поля RecVersion, при последующем обновлении записи в той же транзакции ранее считанный номер сверяется с текущим.
    - Если номера совпадают (т.е. запись не была изменена другой транзакцией), происходит обновление записи.
    - Если номера отличаются, происходит генерация исключения, которое перехватывается и обрабатыватся приложением (catch(Exception:UpdateConflict)) для повтора транзакции или других действий.

    Microsoft Dynamics Ax использует READ UNCOMMITTED для чтения данных вне транзации, внутри транзакций используется READ COMMITTED. Алгоритм работы OCC в Microsoft Dynamics Ax с Microsoft SQL 2000 и Microsoft SQL 2005 несколько различается.

    Внутри транзации блокировки на чтение в Microsoft SQL 2005 не происходит, поскольку чтение происходит из временной таблицы с предварительно созданной копии (см. описание  RCSI выше).

    В Microsoft SQL 2000 при чтении внутри транзации происходит блокирование, если данная запись была уже заблокирована другой транзакцией.  Именно поэтому появилась опция использования READ UNCOMMITED для всех запросов на чтение. Другими словами, эта опция имеет значение только для Microsoft SQL 2000, в Microsoft SQL 2005 включение/выключение опции ничего не дает.
    ‘Грязное чтение’ в данном случае возможно и пользователь может считывать значение из еще не проведенной или откатываемой транзакции.  
    Можно ли рекомендовать данную опцию к использованию? Во-первых, не думаю, что большое количество клиентов будет использовать Microsoft Dynamics Ax 4.0 на Microsoft SQL Server 2000. Во-вторых, речь идет о считывании данных на чтение внутри транзакции (вне транзакции – всегда READ UNCOMMITTED, как в 3.0, так и в 4.0); механизм обработки исключений, упоминавшийся ранее, позволяет управлять ситуцией и не допускать нарушения целостности данных.  В-третьих, данную опцию можно не включать, работа Microsoft Dynamics Ax 4.0 на Microsoft SQL Server 2000 будет аналогично поведению Microsoft Dynamics Ax 3.0.  

    Oracle содержит механизм, похожий на RCSI и поведение Microsoft Dynamics Ax 4.0 в этом случае аналогично поведению на Microsoft SQL Server 2005.

    В текущих версиях Microsoft Dynamics Ax не поддерживается обработка исключений для вложенных транзакций. Т.е. если транзакция (1) содержит вложенные транзакции (2-N), и в какой – то из них произошла генерация исключения, то откатывается вся транзакция целиком  и обработка исключения производится на уровне головной транзакции (1).  Это нельзя назвать ограничением, это вид реализации поддержки целостности транзакций.