Ох уж эти транзакции, блокировки и взаимоблокировки
Блокировки бывают разные…
Транзакционные блокировки
Транзакционные блокировки — это табличные блокировки, устанавливаемые сервером базы данных. При этом разработчик 1С может из встроенного языка системы 1С:Предприятие дать команду серверу базы данных установить транзакционную блокировку. Транзакционные блокировки выполняются на уровне таблиц и служат для обеспечения взаимодействия транзакций, выполняемых одновременно несколькими экземплярами системы 1С:Предприятие в одной базе данных. Эти блокировки снимаются и устанавливаются в процессе обработки транзакций.
В идеале транзакции должны обеспечивать изоляцию изменений, выполняемых в базе данных, т.е. транзакции не должны мешать друг другу. Для одновременного выполнения транзакций используется несколько уровней изоляции транзакций. Высший уровень изоляции — полная изоляция. Чем больше изоляция, тем медленнее работа. Изоляция обычно обеспечивается различными типами блокировок объектов базы данных.
Уровень изоляции транзакции определяет, могут ли другие (конкурирующие) транзакции вносить изменения в данные, измененные текущей транзакцией, а также может ли текущая транзакция видеть изменения, произведенные конкурирующими транзакциями, и наоборот. Каждый последующий уровень поддерживает требования предыдущего и налагает дополнительные ограничения.
MS SQL Server 2000 позволяет использовать следующие уровни изоляции транзакции (перечислим в порядке возрастания уровня изоляции):
• READ UNCOMMITED — незавершенное чтение. Низший уровень изоляции, обеспечивает максимальную параллельность выполнения транзакций. Данный уровень защищает изменяемые мной данные от изменений, которые могут внести конкурирующие транзакции. Если другой транзакции необходимо изменить те же самые данные, то она должна ожидать завершения изменения данных моей транзакцией. Однако чтение данных разрешено. Таким образом этот уровень изоляции допускает чтение незавершенных изменений данных.
На этом уровне выполняется запрещение «загрязнения» данных, т.е. этот уровень требует, чтобы изменять данные могла только одна транзакция; если другой транзакции необходимо изменить те же данные, она должна ожидать завершения первой транзакции
• READ COMMITED — обеспечивает запрет «грязного» чтения. Если моя транзакция начала изменять данные, то конкурирующая транзакция не может не только измененить, но даже прочитать их до завершения моих изменений. После того, как мои изменения закончены, конкурирующие транзакции могут читать данные, не дожидаясь окончания моей транзакции в целом. Таким образом существует проблема неповторяемого чтения.
На этом уровне выполняется запрещение «грязного» чтения. Если транзакция начала изменение данных, то никакая другая транзакция не сможет прочитать их до завершения первой
Проблема неповторяемого чтения является следствием неоднократного считывания транзакцией одних и тех же данных. Во время выполнения первой транзакции другая может внести в данные изменения, поэтому при повторном чтении первая транзакция получит уже иной набор данных, что приводит к нарушению их целостности или логической несогласованности
• REPEATABLE READ — обеспечивает повторяемость чтения данных. Если моя транзакция начинает читать данные, то другая транзакция не может их изменить до окончания моей транзакции.
На этом уровне выполняется запрещение неповторяемого чтения. Если транзакция считывает данные, то никакая другая транзакция не сможет их изменить. Таким образом, при повторном чтении они будут находиться в первоначальном состоянии
• SERIALIZABLE — последовательное выполнение. Этот уровень изоляции является максимальным и обеспечивает полную изоляцию транзакций друг от друга. Решаются все рассмотренные проблемы, включая проблему «фантомов».
На этом уровне выполняется запрещение фантомов. Если транзакция обращается к данным, то никакая другая транзакция не сможет добавить новые или удалить имеющие строки, которые могут быть считаны при выполнении транзакции. Реализация этого уровня блокирования выполняется путем использования блокировок диапазона ключей. Подобная блокировка накладывается не на конкретные строки таблицы, а на строки, удовлетворяющие определенному логическому условию.
READ UNCOMMITED | ||
моя | конкурирующая | |
Чтение | да | |
Изменение | да | нет |
READ COMMITED | ||
моя | конкурирующая | |
Чтение | нет условное | |
Изменение | да | нет |
REPEATABLE READ | ||
моя | конкурирующая | |
Чтение | да | да |
Изменение | нет | |
SERIALIZABLE | ||
моя | конкурирующая | |
Чтение | да | нет |
Изменение | нет |
Уровни изоляции транзакций при различных видах блокировок в различных типах баз данных, поддерживаемых платформой 1С
Автоматические блокировки | Управляемые блокировки | |||
Вид базы данных | Вид блокировки | Уровень изоляции транзакций | Вид блокировки | Уровень изоляции транзакций |
Файловая БД | Таблиц | SERIALIZABLE | Таблиц | SERIALIZABLE |
MS SQL Server | Записей | REPEATABLE READ или SERIALIZABLE | Записей | READ COMMITED |
IBM DB2 | Записей | REPEATABLE READ или SERIALIZABLE | Записей | READ COMMITED |
PostgreSQL | Таблиц | SERIALIZABLE | Записей | READ COMMITED |
Oracle Database | Таблиц | SERIALIZABLE | Записей | READ COMMITED |
Со стороны 1С есть три режима работы конфигурации, которые определяются свойством объекта конфигурации «Режим управления блокировкой данных»:
«Автоматический», «управляемый», «автоматический и управляемый».
Режимы устанавливаются в целом для конфигурации (см. «Свойства конфигурации» в конфигураторе): «автоматический», «управляемый» и «автоматический и управляемый» и для объектов конфигурации: «автоматический» и «управляемый»
Автоматический — менеджер управляемых блокировок 1С:Предприятия не задействуется. Используются автоматические блокировки, устанавливаемые СУБД. При этом в СУБД (не вдаваясь в отличия разных СУБД) используется уровень изоляции транзакций REPEATABLE READ или SERIALIZABLE.
Управляемый — задействуется менеджер управляемых блокировок 1С:Предприятия. Управляемые блокировки расставляет платформа при выполнении методов встроенного языка, модифицирующих данные. Управляемые блокировки может расставлять разработчик из встроенного языка. Если при этом возникает конфликт с имеющимися блокировками, выполнение встроенного языка останавливается. Если конфликта не возникает, то выполнение продолжается и запрос «уходит» в СУБД. После этого СУБД, естественно, устанавливает собственные блокировки. При этом в СУБД используется другой уровень изоляции транзакций — READ COMMITED. Этот уровень изоляции транзакций позволяет достичь более высокой параллельности исполнения запросов, но сам по себе не обеспечивает целостность и непротиворечивость данных во всех случаях. Поэтому и требуется в определенных ситуациях использовать менеджер управляемых блокировок 1С:Предприятия.
Если для конфигурации в целом выбран режим Автоматический и управляемый, то это значит, что часть транзакций может исполняться в автоматическом режиме, а другая часть — в управляемом режиме. Такой режим позволяет переводить прикладное решение в режим управляемых блокировок частями, постепенно.
Управляемые блокировки.
Для установки управляемой блокировки из встроенного языка разработчик 1С использует команду:
НачатьТранзакцию(РежимУправленияБлокировкойДанных.Управляемый);
Команда «НачатьТранзакцию» открывает транзакцию в базе данных. Транзакция предназначена для записи в информационную базу согласованных изменений. Все изменения, внесенные в информационную базу после начала транзакции, будут затем либо целиком записаны, либо целиком отменены. При этом параметр РежимУправленияБлокировкойДанных.Управляемый говорит о том, что в данной транзакции должны выполняться управляемые блокировки.
Установка параметра «РежимУправленияБлокировкойДанных» имеет смысл, если для свойства конфигурации «Управления блокировкой данных» выбрано значение «Автоматический и Управляемый».
- Если значение параметра «РежимУправленияБлокировкойДанных.Автоматический», то данная транзакция будет выполняться в режиме автоматических блокировок.
- Если значение параметра «РежимУправленияБлокировкойДанных.Управляемый», то в данной транзакции будут выполняться управляемые блокировки.
Примечание. Если к моменту вызова данного метода была начата транзакция, выполняющаяся в автоматическом режиме управления блокировками, то установка значения параметра «РежимУправленияБлокировкойДанных.Управляемый» не приведет к изменению режима управления блокировками.
Если к моменту вызова данного метода была начата транзакция, выполняющаяся в управляемом режиме блокировок, то установка значения параметра Автоматический приведет к возникновению исключительной ситуации, которая может быть обработана конструкцией Попытка… Исключение… КонецПопытки.
Значение по умолчанию: Автоматический
При этом задействуется механизм 1С «управляемых блокировок».
Вообще, команда
НачатьТранзакцию(РежимУправленияБлокировкойДанных.Управляемый)
указывает лишь, что данная транзакция планируется к выполнению в режиме управляемых блокировок. Но что будет происходить на самом деле, какой именно режим блокировок «сработает» — это отдельный вопрос, т.к. есть много «мест», позволяющих указать режим блокировок:
— транзакция, открытая ранее и не закрытая
— транзакции, открываемые неявно при выполнении методов встроенного языка, модифицирующих данные
— свойство конкретного объекта конфигурации Режим управления блокировкой данных
Не суть, но смысл в том, что нужно анализировать весь код целиком и сами объекты конфигурации тоже.
Пример управляемой блокировки на языке 1С:
НачатьТранзакцию(РежимУправленияБлокировкойДанных.Управляемый); текБлокировка = Новый БлокировкаДанных; тРег = текБлокировка.Добавить("РегистрСведений.НашРегистр"); тРег.Режим = РежимБлокировкиДанных.Исключительный; ... ЗафиксироватьТранзакцию();
Более подробный пример см. тут: Управляемый режим блокировки данных
Управляемые блокировки не нужно снимать после фиксации транзакции, этот вид блокировок при окончании транзакции снимается автоматически.
Объектные блокировки
Кроме транзакционных блокировок, существуют еще так называемые объектные блокировки — пессимистические и оптимистические.
Пессимистические блокировки, в частности, нужно отменять при фиксации транзакции (но при этом они сами автоматически снимаются при откате транзакции).
Пессимистическая объектная блокировка, осуществляемой командой вида
ТекОбъект.Заблокировать();
Где ТекОбъект – это объект, например, справочника «Номенклатура», предварительно полученный, например, таким выражением:
Справочники.Номенклатура.НайтиПоКоду(«000001»).ПолучитьОбъект();
Начиная с версии платформы 8.3.16 пессимистическая объектная блокировка, в клиент-серверном варианте, будет безусловно снята кластером серверов при выполнении всех следующих условий:
- Выполняется попытка снять объектную блокировку, установленную другим пользователем (в удаленном клиентском приложении).
- Для снятия блокировки используется система взаимодействия.
- Удаленное клиентское приложение в течении 5 секунд, после отправки сообщения системы взаимодействия, не сняло блокировку.
на сайте http://1c.ru , пишут что ORACLE Тоже записи блокирует, а не таблицы