Транзакция внутри транзакции 1с

Транзакция внутри транзакции 1с

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

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

1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

Попытка
. // чтение или запись данных
ДокументОбъект.Записать()
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
. // дополнительные действия по обработке исключения
КонецПопытки;

Попытка
. // чтение или запись данных
ДокументОбъект.Записать()
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
. // дополнительные действия по обработке исключения
КонецПопытки;

1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

НачатьТранзакцию();
Попытка
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("Документ.ПриходнаяНакладная");
ЭлементБлокировкиДанных.УстановитьЗначение("Ссылка", СсылкаДляОбработки);
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();

. // чтение или запись данных

ЗаписьЖурналаРегистрации(НСтр("ru = ‘Выполнение операции’"),
УровеньЖурналаРегистрации.Ошибка,
,
,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

ВызватьИсключение; // есть внешняя транзакция

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

1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию , когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

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

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

Попытка
ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
. // действия по заполнению объекта
ДокументОбъект.Записать();
Исключение
. // действия по обработке исключения
КонецПопытки;

НачатьТранзакцию();
Попытка
ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
. // действия по заполнению объекта
ДокументОбъект.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
КонецПопытки;

1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью , ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

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

Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

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

Читайте также:  Как пользоваться мобильным интернетом на смартфоне

2. Ограничение на длину транзакции.

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

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

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

2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

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

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

Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

  • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию;
  • блокировки, установленные в транзакции, остаются до конца транзакции;
  • на сервере 1С:Предприятия блокировки занимают оперативную память;
  • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.

Все это в целом может снижать эффективность использования ресурсов.

2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

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

Транзакция — это неделимая с точки зрения воздействия на базу данных последовательность операций манипулирования данными. Она выполняется по принципу «все или ничего» и переводит базу данных из одного целостного состояния в другое целостное состояние. Если по каким-либо причинам одно из действий транзакции невыполнимо или произошло какое-либо нарушение работы системы, база данных возвращается в то состояние, которое было до начала транзакции (происходит откат транзакции).

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

Читайте также:  Как разделить числа на две группы

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

Использование явного вызова транзакций

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

● при окончании выполнения встроенного языка (обработчик события, внешнее соединение, automation-сервер);

● при передаче управления с сервера на клиента.

Если количество вызовов методов ЗафиксироватьТранзакцию( ) или ОтменитьТранзакцию() превышает количество вызовов метода НачатьТранзакцию() , то при выполнении лишнего вызова метода ЗафиксироватьТранзакцию() или ОтменитьТранзакцию() будет порождено исключение. Таким образом, схема работы с транзакцией в общем виде может выглядеть следующим образом:

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

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

Восстановимые ошибки — это ошибки, не вызывающие серьезных нарушений в работе системы «1С:Предприятие». В случае возникновения восстановимой ошибки дальнейшая работа системы может быть продолжена. При этом, естественно, сама операция, вызвавшая ошибку, прекращается, и вызывается исключение, которое может быть перехвачено и обработано конструкцией

Попытка … Исключение … КонецПопытки.

Вложенный вызов транзакций

В рамках уже выполняемой транзакции можно обращаться к процедурам НачатьТранзакцию(), ЗафиксироватьТранзакцию() и ОтменитьТранзакцию() . Например, может использоваться следующая схема вызовов:

// Вложенный вызов транзакции

// Вложенный вызов транзакции

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

ВНИМАНИЕ! Система «1С:Предприятие» не поддерживает вложенных транзакций. Это означает, что всегда действует только транзакция самого верхнего уровня.

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

Влияние транзакций на работу программных объектов

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

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

Читайте также:  Не работает клавиатура на удаленном рабочем столе

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

● при отмене транзакции признак проведения документа восстанавливает значение, которое было до начала транзакции;

● если объект был создан и записан в транзакции, то при откате транзакции очищается значение ссылки;

● если объект создавался вне транзакции и при записи его в транзакции использовался код/номер, сгенерированный автоматически, то при отмене транзакции код/номер очищается.

В рамках подготовки к сертификации 1С «Эксперт» в преддверии двух очень важных и глобальных тем — блокировок и взаимоблокировок хотелось бы разобрать то, без чего невозможны вышеназванные понятия, — транзакция СУБД.

Что такое транзакция

Транзакция — логически связанная, неделимая последовательность действий. Транзакция может быть либо выполнена целиком, либо вообще не выполнена. Для фиксации транзакции в СУБД используется метод COMMIT.

Типичный пример транзакции — перевод денежных средств с одного счета на другой:

  1. начать транзакцию;
  2. прочесть количество денежных средств на счету номер 123;
  3. уменьшить баланс счета 123 на 100 рублей;
  4. сохранить баланс счёта номер 123;
  5. прочесть количество денежных средств на счету номер 321;
  6. увеличить баланс на 100 рублей;
  7. записать новое количество денежных средств на счете 321;
  8. зафиксировать транзакцию.

Получите 267 видеоуроков по 1С бесплатно:

Как мы видим, если транзакция выполнена не полностью, то она не имеет смысла.

Ключевые требования (ACID) к транзакционной СУБД

Одним из наиболее распространённых наборов требований к транзакциям и транзакционным СУБД является набор ACID (Atomicity, Consistency, Isolation, Durability). Это те свойства, которыми должна обладать любая транзакция:

  • Атомарность (Atomicity) — никакая транзакция не должна быть зафиксирована частично;
  • Согласованность (Consistency) — система находится в согласованном состоянии до начала транзакции и должна остаться в согласованном состоянии после завершения транзакции;
  • Изолированность (Isolation) — во время выполнения транзакции параллельные транзакции не должны оказывать влияние на её результат;
  • Надежность (Durability) — в случая сбоя изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу.

Транзакции в 1С

Транзакции в 1С 8.3 и 8.2 создаются как автоматически, так и описываются разработчиками.

С помощью метода ТранзакцияАктивна() можно узнать, активна ли транзакция.

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

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

По окончании транзакции её необходимо зафиксировать:

Если Вы хотите отменить действия транзакции, необходимо выполнить метод:

1С не поддерживает вложенных транзакций. Поэтому, если Вы несколько раз открываете транзакцию, она «сливается» в одну. Если же Вы фиксируете или отменяете её, то это действие производится со всеми транзакциями, активируемыми ранее.

Если я не понятно расписал, рекомендую видеолекцию от коллег:

К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.

Ссылка на основную публикацию
Тест эксель на собеседовании
Если вы хоть раз пытались устроиться на работу или же работаете на должности, в круг обязанностей которой входит принятие людей...
Тарифы мтс смарт 400 руб
С того момента как тариф «Смарт» стал доступен для активации, он претерпел множество изменений. Они касаются размера абонентской платы, количества...
Тарифы ростелекома на домашний интернет
Полный список актуальных тарифов Ростелеком для города Москва. Подключай тарифы Rostelecom в Москве бесплатно и пользуйся качественными услугами интернета и...
Тестирование cd и dvd дисков
В этой статье я опишу программу тест Nero CD DVD Speed, которая разработана компанией "Nero Softwsre AG". С помощью программы...
Adblock detector