Организация вложенных транзакций в 1С на примере трассировки ошибок при записи, проведении или отмене проведения документа

08.07.21

Разработка - Механизмы платформы 1С

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

Введение:

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

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

В процессе записи/проведения/отката ДокОбъект выполняется множество функций и проверок, возможно возникновение ошибок, которые в режимах работы пользователя отображаются у него на экране в виде сообщений, а сам документ не проводится (Отказ = Истина).

Когда то же самое происходит (запись/проведение/откат проведения ДокОбъект)  через WebService, то все сопутствующие, проясняющие причину ошибки операции утеряны и в итоге видна только ошибка совершения операции записи/проведения/отката документа.

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

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

Решение:

Создадим РегистрыСведений: "ТекстОшибокИнтеграции" с измерениями"ВнешнийИдентификатор", "Индекс" и реквизитом "ТекстОшибки".

Для решения задачи предлагается использовать WebService.

Для этого необходимо создать WebService и функцию, которая будет производить запись информации в наш регистр сведений.

 
 функция ВебСервиса - запись сообщений об ошибках в транзакции, для организации трассировки

 

// функция ВебСервиса - запись сообщений об ошибках в транзакции, для организации трассировки
Функция SetTextError(Numb, Error)
	ДобавитьТекстОшибкиПоВнешнемуИдентификатору(Numb, Error);
	Возврат "1";
КонецФункции

 

 
 процедура общего модуля (или менеджера регистра)

 

//процедура общего модуля (или менеджера регистра) - запись сообщений об ошибках в транзакции, для организации трассировки
Процедура ДобавитьТекстОшибкиПоВнешнемуИдентификатору(ВнешнийИдентификатор, НовыйТекстОшибки) Экспорт
	
	Если НЕ ЗначениеЗаполнено(ВнешнийИдентификатор) Тогда		
		Возврат;
	КонецЕсли;
		
	Если ЗначениеЗаполнено(НовыйТекстОшибки) Тогда		
		
		НаборЗаписей = РегистрыСведений.ТекстОшибокИнтеграции.СоздатьНаборЗаписей(); 		
		НаборЗаписей.Отбор.ВнешнийИдентификатор.Установить(ВнешнийИдентификатор); 
		НаборЗаписей.Прочитать();
		НовыйИндекс = НаборЗаписей.Количество() + 1;
		
		НоваяЗапись = НаборЗаписей.Добавить();
		НоваяЗапись.ВнешнийИдентификатор = ВнешнийИдентификатор;
		НоваяЗапись.Индекс = НовыйИндекс;
		НоваяЗапись.ТекстОшибки = НовыйТекстОшибки;
		
		НаборЗаписей.Записать();

	КонецЕсли;
	
КонецПроцедуры

 

Технология работы 1С в этом случае такова

- при вызове функции:

ДокОбъект.Записать(пРежимЗаписиДокумента);

Во всех местах, где происходит Отказ = Истина и выводится сообщение об ошибке нам необходимо вставить программный код по вызову функции SetTextError() нашего веб-сервиса, примерно таким образом:

Прокси.SetTextError(пВнешнийИдентификатор, НовыйТекстОшибки);

, где Прокси - это предварительно выполненное соединение с нашим веб-сервисом текущей базы, по следующему шаблону:

мWebCервис = пВнешнееСоединение.Сервер;
мПользователь = пВнешнееСоединение.Пользователь;
мПароль	= пВнешнееСоединение.Пароль;
			
мURIПространстваИменСервиса = пВнешнееСоединение.URIПространстваИменСервиса;
мИмяСервиса = пВнешнееСоединение.ИмяСервиса;
мИмяТочкиПодключения = пВнешнееСоединение.ИмяТочкиПодключения;
		
ОпределениеСервиса = Новый WSОпределения(мWebCервис, мПользователь, мПароль);
Прокси 	= Новый WSПрокси(ОпределениеСервиса, мURIПространстваИменСервиса, мИмяСервиса, мИмяТочкиПодключения);
Прокси.Пользователь = мПользователь;
Прокси.Пароль = мПароль;

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

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

 
 мояфункция_ПолучитьИнформациюТрассировкиОтмененнойТранзакции()

 

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

 

Вывод:

Можно организовать через веб-сервис "вложенную транзакцию", в которой выполнить задачу и зафиксировать в СУБД запись каких-то данных, которые сохранятся даже при отмене основной транзакции.

Конечно, предложенный метод - это не "вложенная транзакция" в чистом виде, как она есть в СУБД. Но для решения некоторых практических задач такая методика будет полезной.

 

транзакции трассировка

См. также

Сервисы интеграции без Шины и интеграции

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    3440    dsdred    16    

66

Как готовить и есть массивы

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

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

24.01.2024    8001    YA_418728146    25    

69

Планы обмена VS История данных

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    8248    dsdred    44    

120

1С-ная магия

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    20423    SeiOkami    46    

125

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    14378    human_new    27    

77

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    10767    YA_418728146    7    

149

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    7166    sebekerga    54    

101
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. RALIN123 38 08.07.21 13:48 Сейчас в теме
		
                НаборПараметровМетода = Новый Массив;
	 	НаборПараметровМетода.Добавить(ДокументСсылка);
	 	НаборПараметровМетода.Добавить(ЕщеПараметр);
		
		//Свойства задания
		КлючЗадания=Строка(Новый УникальныйИдентификатор());
		НаименованиеЗадания="НаименованиеЗадания";
		//Запустим
		Задание = ФоновыеЗадания.Выполнить("ИмяОбщегоМодуляСервер.ИмяМетодаКоторыйБудетВызванВВложеннойТранзакции", НаборПараметровМетода,КлючЗадания,НаименованиеЗадания);
		//Будем завершать ожидания в попытке
		МассивЗаданий=Новый Массив;
		МассивЗаданий.Добавить(Задание);
		
		Попытка
	 		ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
		Исключение
			//Если метод, который выполняется в фоновом задание, выкенет крит то мы попадем сюда, обновим свойства задания
			Задание=ФоновыеЗадания.НайтиПоУникальномуИдентификатору(Задание.УникальныйИдентификатор);
			Если Задание.Состояние=СостояниеФоновогоЗадания.ЗавершеноАварийно
				И НЕ Задание.ИнформацияОбОшибке=Неопределено Тогда
				//Прокинем ошибку вызывающему коду
				ВызватьИсключение Задание.ИнформацияОбОшибке.Описание;
			КонецЕсли;
		КонецПопытки;
Показать


Все делается куда проще, не нужно запускать ракету такую как веб сервис.
Просто код, который должен быть в вложенной транзакции, изолируйте в фоновое задание.
rpgshnik; ovasiliev; mysm; Cmapnep; AneJIbcuH; +5 Ответить
2. Smirnov1980 7 09.07.21 05:36 Сейчас в теме
Конечно, можно и так, это второй вариант решения.
3. user621724_Dimav1979 406 09.07.21 06:40 Сейчас в теме
Ничего не понял, но было очень интересно.
vakham; asmuk; Interrupted; +3 Ответить
4. mysm 86 09.07.21 08:25 Сейчас в теме
Хорошая идея. Можно ещё через параметры сеанса такое сделать. В БСП есть параметр БуферОбмена для таких вещей.
5. ovasiliev 6 10.07.21 11:27 Сейчас в теме
Весь мир использует для этого ФоновыеЗадания.Выполнить(), но нам не нужны кондовые пути....
6. Smirnov1980 7 12.07.21 05:49 Сейчас в теме
(5) Добрый день, в (1) уже предложен вариант использовать Фоновые задания, вы видите что можно дополнить что-то к этому?

Лично мое мнение что в случае, приведенном в статье (когда веб-сервис настроен и сессия и так вызвана этим сервисом) можно запустить еще его раз, это надежнее*,чем фоновое задание.
*О сбоях в работе фоновых заданий слышал, а о сопоставимых проблемах с веб-сервисами нет.
7. ovasiliev 6 12.07.21 06:18 Сейчас в теме
(6) Вы правда считаете, что веб-сервис - эта некая волшебная сущность, а не кусок кода со своими свойствами, методами и потенциальными сбоями, выполняющийся в том же фоновом задании? И только тем в данной ситуации и ценный, что запускает фоновое задание?
8. dabu-dabu 296 12.07.21 16:37 Сейчас в теме
Чтобы получить тексты сообщений, например для возврата веб-сервисом, достаточно воспользоваться функцией ПолучитьСообщенияПользователю
9. Smirnov1980 7 13.07.21 07:04 Сейчас в теме
(8) Спасибо за дельный совет. Тема именно "сообщений" приведена для примера.
Оставьте свое сообщение