Управляемые блокировки 1С

Хочу рассмотреть вопросы и подготовку к сертификации. Учить правильные ответы плохой путь, а вот понимать ответы и применять их, вы тем самым становитесь на путь к уровню «1С:Эксперт». По сути это цикл записей с расширенными ответами на несколько вопросов из тестов.

В случае, если управляемую блокировку установить не удалось в технологическом журнале будут зарегистрировано событие TLOCK.

В простых случаях, чтобы найти виновника таймаута или взаимной блокировки на управляемых блокировках, достаточно найти какую именно управляемую блокировку, несовместимую с блокировкой-жертвой, установило соединение, указанное в WaitConnections.

• ИТС: Мониторинг на продукционных серверах

Эскалация (укрупнение) блокировок это повышение гранулярности блокировки (lock granularity, в некоторых источниках — lock level, «уровень блокируемых данных»). Это процесс преобразования многих мелкогранулированных блокировок в меньшее число крупногранулированных блокировок при вероятном увеличении конкуренции параллелизма.
Эскалации бывают на СУБД и в менеджере управляемых блокировок. Их поведение различно. Различие состоит в том, что если в момент попытки эскалации на СУБД MS SQL кто-то другой будет держать блокировку, то эскалации не произойдет, но при этом транзакция дальше продолжит свое выполнение. Если в «1С:Предприятие» кто-то другой будет держать блокировку, то «эскалирующаяся» транзакция попадет в ожидание от всех, кто еще держит блокировки на этом ресурсе. Если в «1С:Предприятие» не получится проэскалироваться в течение N (по умолчанию 20) секунд, то транзакция получит таймаут.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 58-60.

Объектная блокировка — предназначена для того, чтобы запретить изменение данных определенного объекта другими сеансами или данным сеансом до тех пор, пока блокировка не будет снята этим объектом встроенного языка. Эскалация объектной блокировки невозможна.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 48-49.

Для регистра сведений, подчиненного регистратору, пространства блокировок «DIMS» и «RECORDER» не конфликтуют.

Эскалацию управляемых блокировок запретить нельзя.

Эскалация управляемой блокировки для ресурса, в случае включения в этот ресурс общих реквизитов при работе из разделенного сеанса, возникнет только в рамках области данных.

Чтение наборов записей регистров через объектную модель приводит к наложению управляемой блокировки.
Получение прикладного объекта через ПолучитьОбъект() всегда происходит с использованием объектной блокировки.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 50.

Если метод Заблокировать() коллекции БлокировкаДанных выполняется вне транзакции блокировки установлены не будут.

Чтобы определить время, которое управляемая блокировка ожидала освобождения ресурса необходимо смотреть на свойства события Lock:Aсquired в профайлере.

Блокирующее чтение остатков в начале транзакции
1.1. В ряде случаев необходимо выполнять блокирующее чтение итогов. Примером такой задачи является контроль остатков при проведении документа. Если в результате проведения документа остатки станут отрицательными, то транзакция должна быть отменена (проводить такой документ нельзя).
1.2. Операция чтения остатков должна быть блокирующей, то есть необходимо запретить двум пользователям одновременно читать один и тот же остаток за период, счет и значение измерения.
Если чтение будет неблокирующим, то возможна ситуация, при которой два пользователя одновременно прочитают один и тот же остаток (например 10 единиц) и примут решение о возможности списания части этого остатка. Если сумма списаний двух пользователей будет больше 10, то в итоге остаток получится отрицательным.
Например, первый пользователь спишет 8 единиц (8 меньше 10, следовательно операция разрешена), а второй пользователь спишет 6 единиц (на таком же основании). Результатом будет -4 единицы остатка, что недопустимо с точки зрения прикладной логики системы.
2. Обычно, для контроля остатков используется запрос в модуле набора записей регистра, который идет перед записью набора. При этом возможны следующие проблемы:

  • Разработчик, как правило, не контролирует порядок записи движений в разные регистры — запись обычно осуществляется автоматически платформой 1С:Предприятия. Запрос контроля остатков реализуется в модуле набора записей и вызывается при записи движений регистра. Если этот регистр будет записываться в начале транзакции (например, первым), то установленная блокировка будет мешать работе других пользователей в течение длительного периода времени (пока будут записываться все остальные регистры), и ее влияние на производительность системы может оказаться неоправданно большим.
  • В некоторых случаях, возможно, нет необходимости в контроле остатков, поскольку записываемые движения заведомо не могут привести к получению отрицательных остатков.

Для того чтобы минимизировать влияние блокирующего чтения остатков на производительность системы, необходимо:

  • Проанализировать, какие именно остатки нуждаются в блокирующем чтении и при каких обстоятельствах. Например, контроль остатков не требуется при проведении приходного документа, поскольку он может только увеличить остатки. Так же не требуется контролировать остатки при перепроведении документа, который списывает в этот раз не больше остатков чем при первом проведении (этот контроль уже проводился). И так далее.
  • В начале транзакции (например, в обработчике ОбработкаПроведения документа) в явном виде записать движения по всем регистрам, которые в данном случае не требуют контроля остатков. Следует всегда придерживаться одинакового порядка записи регистров (например, алфавитного). Необходимо обратить внимание на то, что у всех записываемых регистров накопления и бухгалтерии должен быть включен разделитель итогов, а у наборов записей свойство БлокироватьДляИзменения должна быть установлена в значение Ложь.
  • Выполнить все остальные действия, которые должны быть выполнены в рамках этой транзакции.
  • В самом конце транзакции в явном виде записать движения по тем регистрам, которые требуют контроля остатков. Для наборов записей этих регистров следует установить опцию БлокироватьДляИзменения в значение Истина. Это необходимо для предотвращения взаимоблокировки. Именно в этот момент времени будет установлена блокировка остатков регистра по данному набору значений измерений.
  • Для каждого регистра выполнить запрос контроля остатков. Следует обратить внимание, что в данном случае нет необходимости использовать явную управляемую блокировку (опцию ДЛЯ ИЗМЕНЕНИЯ — в автоматическом режиме), поскольку проверяемые остатки уже заблокированы их записью на предыдущем шаге. Запрос должен считывать только отрицательные остатки по заданному набору значений измерений. Если такие записи имеются, то транзакция должна быть отменена. Если запрос вернул пустой результат, то транзакция должна быть зафиксирована.

ИТС: Блокирующее чтение остатков в начале транзакции

На этот регистр в других транзакциях нельзя будет поставить блокировки, которые будут принадлежать плоскости «первой» или «второй» блокировок, установленных в первой транзакции.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 49.

По технологическому журналу по событию TLOCK можно определить, какие именно управляемые блокировки были установлены.

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

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 49.

Блокировать необходимые данные партиями, каждую — в отдельной транзакции, контроль успешности выполнения действий со всеми партиями делать внешними средствами.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 60.

Эскалация определяется, например, по наличию в трассировке профайлера SQL Server события Lock:Escalation.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 59.

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

Уровни блокировки ресурсов управляемыми блокировками «1С:Предприятие»:
Разделяемый (Shared) — разделяемая блокировка позволит конкурирующему процессу установить разделяемую блокировку по этому же условию, но не позволит установить исключительную блокировку.
Исключительный (Exclusive) — исключительная блокировка не позволит конкурирующему процессу установить разделяемую или исключительную блокировку по этому же условию.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 49.

Виды объектных блокировок поддерживаемых в системе «1С:Предприятие»:
Пессимистическая блокировка исходит из предположения, что «если что-то плохое может случиться, это обязательно случится», то есть, если мы выполняем действие, конкурентное выполнение которого может привести к «поломке» данных, то правильным будет исключить возможность конкурентного исполнения.
Оптимистическая блокировка предполагает, что во время обновления записи в базе мы будем единственными, кто ее меняет. В большинстве случаев, так оно и есть (оптимизм оправдан). Но перед этим необходимо точно удостовериться, что запись с момента ее чтения не изменилась.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 49.

Полей пространства блокировок для Константа.<имя> — нет.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для Перерасчет.<имя> — ВидРасчета.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для Перерасчет.<имя>.НаборЗаписей — ОбъектПерерасчета.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для Последовательность.<имя> — <имя измерения>.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для Последовательность.<имя>.НаборЗаписей — Регистратор.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поля пространства блокировок для РегистрБухгалтерии.<имя> —
• Период;
• <вид движения> — значение системного перечисления ВидДвиженияБухгалтерии;
• Счет — обязательное поле;
• Субконто;
• <вид субконто>;
• <имя измерения>.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для РегистрБухгалтерии.<имя>.НаборЗаписей — Регистратор.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поля пространства блокировок для РегистрНакопления.<имя> —
• Период;
• <имя измерения>.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для РегистрНакопления.<имя>.НаборЗаписей — Регистратор.

• ИТС: Блокировки данных в 1С:Предприятии 8

Избыточная блокировка — блокировка, не обусловленная бизнес-логикой приложения.

• ИТС: Типичные причины избыточных блокировок и методы оптимизации

Поля пространства блокировок для РегистрРасчета.<имя> —
• ПериодРегистрации;
• ПериодДействия;
• <имя измерения>.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для РегистрРасчета.<имя>.НаборЗаписей — Регистратор.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поля пространства блокировок для РегистрСведений.<имя> —
• Период — если есть;
• <имя измерения>.

• ИТС: Блокировки данных в 1С:Предприятии 8

Поле пространства блокировок для РегистрСведений.<имя>.НаборЗаписей — Регистратор.

• ИТС: Блокировки данных в 1С:Предприятии 8

Пессимистическая блокировка гарантирует, что пользователь, начав изменять данные объекта, сможет записать эти изменения в информационную базу, а так же проблему неповторяемого чтения для объектов, редактируемых в форме.
Неповторяющееся чтение (non-repeatable read) — при повторном чтении в рамках одной и той же транзакции оказывается, что ранее прочитанные данные изменены или удалены;

• ИТС: Блокировки данных в 1С:Предприятии 8

Не важно, блокировались данные на уровне записей (строк), на уровне диапазона ключа или на уровне страницы. После эскалации они окажутся заблокированы на уровне таблицы, т.е. эскалация всегда происходит до уровня таблицы.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 59.

TDEADLOCK — обнаружена взаимоблокировка в управляемом режиме.
TTIMEOUT — превышение максимального времени ожидания транзакционной блокировки.

• ИТС: Описание и расположение служебных файлов

Существует два способа задания условий на поля пространств блокировки:

  • с помощью явного задания имени поля и его значения;
  • с помощью указания источника данных, содержащего необходимые значения

При явном задании имени поля и его значения необходимо использовать метод УстановитьЗначение() объекта ЭлементБлокировкиДанных. В этом случае имя и значение указывают в качестве параметров метода.

• ИТС: Блокировки данных в 1С:Предприятии 8

Уровни блокировки ресурсов управляемыми блокировками «1С:Предприятие»:
Разделяемый (Shared) — разделяемая блокировка позволит конкурирующему процессу установить разделяемую блокировку по этому же условию, но не позволит установить исключительную блокировку.
Исключительный (Exclusive) — исключительная блокировка не позволит конкурирующему процессу установить разделяемую или исключительную блокировку по этому же условию.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 49.

Таблица будет заблокирована целиком:
• в файловом режиме;
• всегда при эскалации блокировок;
• при работе с Oracle Database и PostgreSQL в автоматическом режиме блокировок;
• при использовании Clustered Index Scan или Table Scan в плане запроса;
• при записи пустого набора в пустую таблицу в автоматическом режиме блокировок.

Установленные управляемые блокировки, как разделяемые, так и исключительные, держатся до конца транзакции.

• ИТС: Блокировки данных в 1С:Предприятии 8

Неявные управляемые блокировки платформой устанавливаются при чтении наборов записей и при записи любых объектов.

• ИТС: Блокировки данных в 1С:Предприятии 8
• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 50.

Неявные управляемые разделяемые блокировки платформой устанавливаются при чтении набора записей.

• ИТС: Блокировки данных в 1С:Предприятии 8
• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 50.

Механизм объектных блокировок позволяет оповестить пользователей о захвате объектных данных «1С:Предприятия»: справочников, документов, планов видов характеристик, планов счетов, планов видов расчета, бизнес-процессов, задач, планов обмена.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 48.

Информация, какую именно управляемую блокировку, несовместимую с блокировкой-жертвой, установило соединение, указанное в WaitConnections, может находиться не в том же файле, где есть событие TDEADLOCK или TTIMEOUT. Она может быть в логах другого часа, другого рабочего процесса, и даже, если в кластере несколько серверов – в логах другого сервера.

Встроенный язык не поддерживает возможность явно снять определенную транзакционную блокировку.

Объектная оптимистичная блокировка предполагает, что во время обновления записи в базе данных мы единственные, кто меняет эту запись.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 49.

Объектная пессимистичная блокировка предполагает, что если данные во-время записи в базу могут «поломаться» из-за конкурентного доступа, то они «поломаются», т.е. данные нельзя давать записывать в базу одновременно.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 49.

Поля пространства блокировок Регистратор и <имя измерения> не пересекаются потому, что поле пространства блокировок Регистратор относится к пространству Регистр(Сведений | Накопления | Бухгалтерии).<имя>.НаборЗаписей, а поле <имя измерения> относится к пространству Регистр(Сведений | Накопления | Бухгалтерии).<имя>.

• ИТС: Блокировки данных в 1С:Предприятии 8

Пространства блокировок определены в платформе «1С:Предприятия 8.1» и выше и соответствуют структуре прикладных объектов конфигурации.

• ИТС: Блокировки данных в 1С:Предприятии 8

Пространство блокировок без суффикса НаборЗаписей используется в тех случаях, когда анализируются некоторые данные этого объекта (например, остатки регистра), или когда выполняются какие-либо операции, приводящие к изменению существующих данных объекта (например, восстановление границы последовательности).

• ИТС: Блокировки данных в 1С:Предприятии 8

Пространство блокировок с суффиксом НаборЗаписей используется в тех случаях, когда необходимо заблокировать сами записи данного объекта (например, при добавлении новых записей).

• ИТС: Блокировки данных в 1С:Предприятии 8

Разделение итогов регистров накопления и бухгалтерии работает и в автоматическом режиме управления блокировками, и в управляемом, но в автоматическом режиме свойство БлокироватьДляИзменения вызывает исключительную ситуацию.

С 20000 записей в наборе начинается эскалация управляемых блокировок «1С:Предприятия 8.2».

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 59.

Со 100000 записей в наборе начинается эскалация управляемых блокировок «1С:Предприятия 8.3» в одной транзакции в информационной базе.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 59.

Таймаут на управляемых блокировках расследуется с помощью событий:
TLOCK — управление транзакционными блокировками в управляемом режиме.
TTIMEOUT — превышение максимального времени ожидания транзакционной блокировки.

• ИТС: Описание и расположение служебных файлов

Свойство БлокироватьДляИзменения при попытке использования в автоматическом режиме блокировки вызывает исключительную ситуацию.

• Синтакс-помощник

Правильный порядок событий в технологическом журнале при возникновении таймаута на управляемых блокировках: TLOCK виновника …(возможно, другие TLOCK)… TTIMEOUT TLOCK жертвы …(возможно, другие TLOCK)…

Управляемые блокировки при выполнении запроса не устанавливаются.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 50.

Уровень блокировки — это то, насколько блокировка совместима с другими блокировками, а уровень изоляции — это то, какие допускаются несогласованности при параллельной работе.
Уровень блокировки определяется сущностью выполняемых действий (чтение, обновление, запись), а уровни изоляции, отличные от используемых по умолчанию, могут быть установлены с использованием Transact-SQL или через API (application programming interface) базы данных.

• книга «Настольная книга 1С:Эксперта по технологическим вопросам», издание 2, с. 34-50.

Если в момент эскалации управляемой блокировки по определенному пространству блокировок в этом пространстве уже установлена какая-то несовместимая управляемая блокировка, возникнет ожидание при эскалации блокировки, пока несовместимая блокировка не будет снята либо не будет превышено время ожидания предоставления возможности установки блокировки.

Блокировка — это механизм, с помощью которого сервер (СУБД, а также 1С) синхронизирует одновременный доступ нескольких пользователей к одному фрагменту данных.

Избыточная блокировка — блокировка, не обусловленная бизнес-логикой приложения.

При многопользовательском режиме работы в 1С блокировки данных являются необходимым механизмом. Именно они защищают от ситуаций, похожих на одновременную продажу двумя менеджерами одного и того же товара разным клиентам. В платформе 1С предусмотрено два вида блокировок – управляемый и автоматический. Первый из режимов блокировок в 1С является оптимальным для высоконагруженных систем с большим количеством пользователей. Рассмотрим его подробнее.

Особенности управляемого режима блокировок

В отличие от автоматического, управляемый режим позволяет системе 1С использовать собственный менеджер блокировок и применять менее жесткие правила СУБД. То есть встроенный механизм позволяет учитывать бизнес-логику приложения и более плавно и точно устанавливает ограничения на чтение и запись данных. Смена режима блокировок может дать существенный прирост производительности и позволит сократить количество ошибок блокировок транзакции. Происходит это за счет дополнительной проверки менеджером блокировок на соответствие ограничениям, установленным внутри системы перед тем, как передать запрос СУБД.

Существенный минус заключается в том, что разработчику приходиться самостоятельно контролировать непротиворечивость данных при их вводе и обработке. Вполне вероятно, что после включения режима управляемых блокировок придется написать немало проверок, чтобы достичь прежнего уровня безопасности. Несмотря на это, многие компании предпочитают перейти на управляемый режим, если возможности это позволяют.

При разработке программных проверок и ограничений важно помнить про особенность управляемых блокировок – любая из них держится до конца транзакции. Из этого следует, что программистам надо устанавливать блокировку ближе к концу транзакции, чтобы вероятность ожидания была минимальна. Если вам нужно сделать расчеты и записать их результат, то наложение блокировки правильнее прописать после расчетов.

Еще одной распространенной проблемой блокировок в 1С является импорт документов. Многие разработчики используют достаточно простое решение – при загрузке не проводить документы, а только создавать. А после, с помощью простого механизма, провести все загруженные данные в многопоточном режиме по ключевым характеристикам – номенклатуре, партнерам или складам.

Алгоритм перехода на управляемые блокировки 1С выглядит просто, но неквалифицированный администратор 1С может совершить ошибки, исправить которые будет сложно. Чаще всего бывают проблемы с избыточным или недостаточным уровнем блокировок. В первом случае будут возникать проблемы с быстродействием системы, вплоть до аварийных остановок кластера серверов. Недостаточные блокировки опасны ошибками в учете при одновременной работе пользователей.

Переключение в управляемый режим

Несмотря на то, что ниже будет представлен полный алгоритм перехода на режим управляемых блокировок, выполнять его должен опытный специалист. Если не понимать принципов работы механизма блокировок в 1С и СУБД, то вряд ли получится правильно написать ограничения. Но это относиться к сложным конфигурациям. Для простых конфигураций начинающие разработчики могут успешно закончить процесс переключения режима и набраться опыта:

  • В первую очередь нужно изменить режим управления блокировкой данных для конфигурации. Для этого в конфигураторе откройте дерево конфигурации и в свойствах корневого элемента в разделе «Совместимость» измените режим. Выберите пункт «Автоматический и управляемый», чтобы не возникало ошибок до того, как все объекты будут переведены на новый режим;

Рис.1 Выберите пункт «Автоматический и управляемый»

  • Теперь настает очередь документов. Ведь именно с их помощью мы регистрируем все события, которые нужно контролировать. Начинать перевод на управляемые блокировки 1С нужно с самых загруженных документов. На вкладке «Прочее» указываем режим блокировок «Управляемый»;
  • Находим все регистры, связанные с уже обработанным документом и переводим их в управляемый режим по аналогичному документам методу;
  • Следующий этап включает в себя поиск и изменение всех транзакций с измененными объектами. Сюда входят и явные изменения, включающие ключевые слова «НачатьТранзакцию()», так и все обработчики документов и регистров, включающие транзакции;

НачатьТранзакцию() Для Каждого ДокументНаУдаление ИЗ СпискаДокументов Цикл ОбъектДокумента = ДокументНаУдаление.ПолучитьОбъект(); Попытка ОбъектДокумента.УстановитьПометкуУдаления(Истина); Исключение Отказ = Истина; ОтменитьТранзакцию(); Сообщить(«Не удалось удалить документ » + ОбъектДокумента); Прервать; КонецПопытки; КонецЦикла; ЗафиксироватьТранзакцию();

  • Исключить оператор языка запросов «ДЛЯ ИЗМЕНЕНИЯ». Заменить его можно объектом «БлокировкаДанных» с необходимостью изменить запрос и алгоритм его вызова и обработки.

Последние два этапа являются наиболее сложными и требующими квалификации от разработчика, но именно они являются гарантами поддержания рабочего состояния учета в системе.

Механизм управления блокировками данных в транзакции позволяет осуществлять блокировку изменяемых данных не средствами используемой системы управления базами данных, а средствами платформы. Такое управление блокировками данных выполняется не в терминах данных СУБД, а в терминах предметной области. Благодаря этому блокировки накладываются «точнее» и параллельность работы пользователей повышается.

Конфигурация 1С:Предприятия 8 может работать в одном из трех режимов управления блокировками в транзакции:

  • автоматический;
  • управляемый — стандартный режим для новых конфигураций;
  • автоматический и управляемый.

В автоматическом режиме управления блокировками данных используются уровни изоляции транзакций repeatable read и serializable, обеспечиваемые системой управления базами данных. Эти уровни изоляции транзакций обеспечивают согласованное и целостное чтение данных, и от разработчика не требуется каких-либо дополнительных действий по управлению блокировками.

Управляемый режим позволяет повысить параллельность работы пользователей в клиент-серверном варианте работы за счет использования более низкого уровня изоляции транзакций базы данных (Read Committed). При записи данных в транзакции объекты встроенного языка автоматически блокируют необходимые данные. Разработчику требуется управлять блокировками данных в тех случаях, когда бизнес-логика требует согласованного и целостного чтения данных в транзакции.

Автоматический и управляемый режим позволяет использовать возможность управления блокировками в транзакции только для некоторых объектов конфигурации. Этот режим может использоваться для оптимизации параллельности работы пользователей с отдельными прикладными объектами (например, с несколькими наиболее интенсивно используемыми документами) или для постепенного перевода больших конфигураций в режим управления блокировками в транзакции.

В сводном виде отличия при работе в режиме автоматических блокировок и в режиме управляемых блокировок приведены в следующей таблице:

Наиболее часто необходимость в управлении блокировками данных в транзакции возникает в процессе проведения документов, когда нужно прочитать, а затем записать измененные данные в те же самые таблицы. Например, если выполняется контроль остатков при проведении документа.

Специально для этого у наборов записей регистров накопления и регистров бухгалтерии существует свойство БлокироватьДляИзменения.

Если нужно контролировать остатки, а затем записывать движения в этот же регистр, то это свойство нужно установить для набора записей этого регистра в свойстве Движения.

Действие этого свойства аналогично тому, как если бы разработчик самостоятельно установил (прописал в коде) нужные управляемые блокировки 1С:Предприятия 8. Необходимую управляемую блокировку платформа установит автоматически при записи этого набора записей. В результате другие управляемые транзакции, использующие аналогичную блокировку, не смогут начать читать этот регистр, пока не закончится текущая транзакция.

Ниже приведен пример «ручного» управления блокировками данных при чтении данных регистра накопления УчетНоменклатуры в обработке проведения документа РасходнаяНакладная. В этом примере управляемые блокировки создаются и устанавливаются полностью только средствами встроенного языка.

Блокировки

При работе с объектными данными (справочники, документы, планы счетов и т.д.) система «1С:Предприятие» обеспечивает два вида объектных блокировок: пессимистическую и оптимистическую. Они позволяют выполнять целостные изменения объектов при одновременной работе нескольких пользователей.

Объектная пессимистическая блокировка

Пессимистическая объектная блокировка предназначена для запрета изменений данных объекта, пока блокировка не будет снята. Система (с помощью соответствующих расширений формы объекта) автоматически устанавливает пессимистическую блокировку, в момент, когда пользователь пытается произвести изменение данных объекта. Если после этого другой пользователь, например, попытается выполнить редактирование того же объекта, ему будет выдано сообщение о том, что не удалось заблокировать объект. Когда форма будет закрыта пользователем, данная блокировка будет снята.

Рассмотрим пример.
Войдем в учебную информационную базу под пользователем «Васильев В.В.», откроем форму документа «Поступление товаров 00000000001 от 01.06.2016» и внесем изменения в поле комментарий (рис. 1.3).

Не сохраняя документ войдем в информационную базу под пользователем «Иванов И.И.», откроем тот же документ и попробуем внести изменения в любом реквизите документа. Система не даст нам внести изменения и выдаст сообщение об ошибке (рис. 1.4).

Отсюда следует, что пессимистическая блокировка гарантирует, что пользователь, начав изменять данные объекта, сможет записать эти изменения в информационную базу.

Разработчик используя средства встроенного языка может задействовать пессимистическую блокировку. Используя метод «Заблокировать()» происходит установка пессимистической объектной блокировки, а для снятия используется метод «Разблокировать()».

Давайте рассмотрим другой пример. Под пользователем «Васильев В.В.» в разделе «Нормативно-справочная информация» откроем элемент справочника «Склады» с наименованием «Склад №1» и внесем изменения в наименование (рис. 1.5).

Не сохраняя переключимся в окно информационной базы, который был запущен под пользователем «Иванов В.В.», в разделе «Нормативно-справочная информация» откроем обработку «Удаление объекта». Выберем в качестве удаляемого объекта выберем элемент справочника «Склады» с наименованием «Склад №1» и нажмем «Удалить объект» (рис. 1.6).

В результате система позволит удалить данный элемент справочника и система не выдаст сообщение об ошибке. Дело в том, что операция блокирования не препятствует операции изменения или удаления объекта в базе данных.

Для того, чтобы обеспечить невозможность изменения или удаления заблокированного объект необходимо произвести проверку на блокировку объекта.

Есть два способа проверки:

  1. Метод «Заблокирован()» используется для проверки блокировки объекта базы данных текущим сеансом. Данный метод не предоставляет возможность проверки заблокирован ли объект вообще.
  2. Для проверки заблокирован объект базы данных вообще используется метод «Заблокировать()». Попытка блокировки заблокированного объекта вызывает исключение, которое может быть обработано конструкцией «Попытка…..Исключение…..КонецПопытки».

Пессимистическая блокировка в управляемых формах

При работе с управляемыми формами методы «Заблокировать()», «Разблокировать()» и «Заблокирован()» могут не подойти из-за специфики работы управляемого приложения.

Дело в том, что данные методы используются для объектов базы данных. Объект базы данных существует только на сервере. Получается разработчику придется выполнить серверный вызов, получить объект базы данных путем преобразования основного реквизита формы с помощью метода формы «РеквизитФормыВЗначение». Далее вызывается один из методов объекта «Заблокировать()», «Разблокировать()» или «Заблокирован()». Но данный способ блокировки будет бесполезен, если задача стоит, чтобы объект был заблокирован пока открыта форма, так как полученный объект будет жить до конца серверного вызова.

Для работы с блокировками из управляемой формы необходимо использовать методы: «ЗаблокироватьДанныеФормыДляРедактирования()» и «РазблокироватьДанныеФормыДляРедактирования()». Данные методы используются для блокировки или разблокировки данных основного реквизита формы.

Рассмотрим пример. В разделе «Нормативно-справочная информация» откроем любой элемент справочника «Номенклатура» под пользователем «Васильев В.В.», внесем изменения в наименование и не сохраняя под пользователем «Иванов И.И.» отроем тот же элемент справочника. При попытки внесения изменений система выдаст сообщение об ошибке.

Далее в форме элемента справочника под пользователем «Васильев В.В.» нажмем на кнопку «Разблокировать» (рис. 1.7) и попробуем снова внести изменения в данный элемент справочника под пользователем «Иванов И.И.». В данном случае система даст внести изменения и записать элемент справочника.

Для отключения пессимистической блокировки в управляемых формах в свойстве основного реквизита надо снять флаг «Сохраняемые данные». Данный флаг определяет будет ли при интерактивном редактировании блокироваться данные основного реквизита, или нет рис(1.8).

Оптимистическая блокировка представляет собой проверку, которая выполняется перед записью объекта в базу данных. У объекта есть свойство «ВерсияДанных», которая вместе с объектом считывается из базы данных. Оптимистическая блокировка производит перед записью производит сравнение значения свойства «ВерсияДанных» объекта, который находится в оперативной памяти с значением свойства «ВерсияДанных» объекта находящийся в базе данных. Если значения свойства «ВерсияДанных» у объектов отличается, то оптимистическая блокировка запрещает запись объекта в базу данных и выдает сообщение об ошибке.

Рассмотрим пример.

В разделе «Нормативно-справочная информация» откроем любой элемент справочника «Номенклатура» под пользователем «Васильев В.В.», далее не закрывая форму элемента под пользователем «Иванов И.И.» в разделе «Нормативно-справочная информация» откроем обработку «Изменить объект».

В обработке выберем ту же номенклатуру и нажмем кнопку «Изменить объект». Данная команда добавит в конце наименования «!!!» (рис. 1.9).

После изменения попробуем записать открытый элемент справочника номенклатуры под пользователем «Васильев В.В.». Система выдаст предупреждение о том, что данные объекты были изменены или удалены и не даст записать данный объект (рис. 1.10).

Для отключения оптимистической блокировки необходимо перед записью объекта находящийся в оперативной памяти сравнить версию с версией объекта базы данных. Если версии данных отличаются, то получаем объект из базы данных и переносим изменения в него, далее записываем.

Печать (Ctrl+P)

Управляемые формы. Платформа 1С 8.3

Объект конфигурации Нумераторы в дереве документов обеспечивает порядок нумерации стандартного реквизита документов – Номер .

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

Например, в одной конфигурации создан вид документа
«Страховой полис”, который кроме стандартного реквизита номер , содержит еще реквизит Номер полиса , порядок нумерации которого от контрагента ( исполнителя) документа ( страховой компании).

Для обеспечения уникальности нумерации реквизита Номер полиса в разрезе контрагента, я создал периодический в приделах года, регистр сведения Нумератор Полиса . Этот регистр содержал одно измерение – Контрагент и один ресурс – Номер

Однако, были случай, когда при интенсивном создании документа полиса на основании документа Заказ покупателя без блокировки нумератора создавались дублированные номера полиса. Причина была в том, что новый номер не успевал записаться в регистре сведения Нумератор полиса до того, как поступал новый запрос на получение очередного номера полиса.

Причина кажется не вероятно !.Но факт есть факт. Особенно при сильно загрузке сервера нумератор раздавал один и тот же номер разным полисам потому, что он не успевал его записывать.

Использование метод глобального контекста перед чтением данных нумератора

ЗаблокироватьДанныеДляРедактирования(<Ключ>, <ВерсияДанных>, <ИдентификаторФормы>)

не дает положительный результат, так как этот метод
блокирует данные только для редактирования в управляемой форме, а не для чтения.

Проблема была решена после блокировки счетчика перед чтением с помощью объекта блокировкаДанных:

Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(«РегистрСведений._НумерацияДоговоровСтраховыхКомпаний»);
Блокировка.Заблокировать();

Средствами встроенного языка установка управляемых блокировок внутри явной или скрытой (неявной) транзакции происходит с помощью специального объекта БлокировкаДанных, описание доступных свойств и методов которого можно посмотреть в синтакс-помощнике в ветви Общие объекты ( См рис 1).

Объект блокировкаДанных предназначен для явной блокировки данных от чтения или изменения другими сессиями. Метод заблокировать() устанавливает управляемые блокировки и ждет, когда это возможно – когда блокировка в другой сессии будет снята . По истечению времени ожидания возникает прерывание системы и вызывается ошибка СУБД.

Отмена ( снятие) блокировки происходит автоматически при выходе из транзакции . У данного объекта нет метода типа отмены или снятия блокировки.

Другие примеры блокировки данных из встроенного языка можно посмотреть по ссылке .

В этой статье я рассматриваю следующий практический пример:

Перед записью документа Полис требуется заблокировать Нумератор полиса , если это удалось, модифицировать документ Полис – присвоить очередной номер полиса . В противном случае – проинформировать пользователя об отказе в выполнении операции записи полиса такого вида:

Не удалось заблокировать нумератор полиса. Документ полис не может быть записан . Повторите попытку!

Решение этого примера выполняется в теле обработчика события ПередЗаписьюНаСервере.

Данное событие вызывается перед записью полиса на сервере и выполняется вне транзакции. Можно отменить запись полиса если в теле процедуры-обработчика установить отказ = истина.

&НаСервере Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) Если Не ЗначениеЗаполнено(ТекущийОбъект.НомерПолиса) Тогда НомерПолиса = ПолучитьНомерПолиса (ТекущийОбъект.Контрагент); Если НомерПолиса = 0 Тогда Отказ = Истина; Сообщить(» Не удалось записать полис!. Повторите попытку»); Иначе ТекущийОбъект.НомерПолиса = НомерПолиса; КонецЕсли; КонецЕсли; КонецПроцедуры

Обратите внимание, что вызов функции
ПолучитьНомерПолиса происходит если номер полиса не заполнен. Кроме того, запись полиса отменяется если она возвращает ноль при ее вызове .

Весь программный код можно было бы поместить в модуле объекта в обработчике события ПередЗаписью , а не в модуле управляемой формы полиса.

Программный код пользовательской функции , возвращающей номер полиса и осуществляющей чтение и запись с блокировкой нумератора полиса показан в следующем фрагменте:

&НаСервере Функция ПолучитьНомерПолиса (Контрагент) НачатьТранзакцию(); Попытка Отбор = Новый Структура; Отбор.Вставить(«Контрагент», Контрагент); КлючЗаписи = РегистрыСведений._НумераторПолиса.СоздатьКлючЗаписи(Отбор); ЗаблокироватьДанныеДляРедактирования(КлючЗаписи); // БлокировкаДанных Предназначен для явной блокировки данных от чтения // или изменения другими сессиями. Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить(«РегистрСведений._НумерацияДоговоровСтраховыхКомпаний»); Блокировка.Заблокировать(); Номер=0; Запрос = Новый Запрос; Запрос.Текст = «ВЫБРАТЬ |_НумераторПолисаСрезПоследних.Номер КАК Номер |ИЗ |РегистрСведений._НумераторПолиса.СрезПоследних(, Контрагент = &Контрагент) КАК _НумераторПолисаСрезПоследних ; Запрос.УстановитьПараметр(«Контрагент», Контрагент); Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда Номер = Выборка.Номер; КонецЕсли; Номер = Номер+1; запись = РегистрыСведений._НумераторПолиса.СоздатьМенеджерЗаписи(); запись.Контрагент = Контрагент; запись.Период = ТекущаяДата(); запись.Номер =Номер; Запись.Записать(); РазблокироватьДанныеДляРедактирования(КлючЗаписи); ЗафиксироватьТранзакцию(); Исключение ОтменитьТранзакцию(); Сообщить( «Не удалось заблокировать нумератор. Он уже заблокирован»; Возврат 0; КонецПопытки; Возврат Номер; КонецФункции

Обратите внимание, что блокировка записи происходит до выполнения запроса о чтении номера. Если запись заблокирована вызывается исключение и функция возвращает 0.

Часто блокирование и разблокирование происходит внутри транзакции. Причем, транзакция начинается перед блокированием данных и зафикируется после разблокирования . Вот пример из библиотеки стандартных подсистем при старте отложенного бизнес-процесса

Процедура СтартоватьОтложенныйПроцесс(БизнесПроцесс) Экспорт НачатьТранзакцию(); Попытка ЗаблокироватьДанныеДляРедактирования(БизнесПроцесс); БизнесПроцессОбъект = БизнесПроцесс.ПолучитьОбъект(); // Стартуем бизнес процесс и регистрируем этот старт в регистре. БизнесПроцессОбъект.Старт(); РегистрыСведений.ПроцессыДляЗапуска.ЗарегистрироватьСтартПроцесса(БизнесПроцесс); РазблокироватьДанныеДляРедактирования(БизнесПроцесс); ЗафиксироватьТранзакцию(); Исключение ОтменитьТранзакцию(); ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()); ТекстОшибки = НСтр(«ru = ‘Во время отложенного старта этого процесса произошла ошибка: |%1 |Попробуйте запустить процесс вручную, а не отложенно.'»); Описание = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( ТекстОшибки, ОписаниеОшибки); РегистрыСведений.ПроцессыДляЗапуска.ЗарегистрироватьОтменуСтарта(БизнесПроцесс, Описание); КонецПопытки; КонецПроцедуры 0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *