Организация вложенных транзакций в 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    2765    dsdred    16    

60

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

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

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    6378    dsdred    59    

86

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

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

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

24.01.2024    6257    YA_418728146    25    

68

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

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

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

11.12.2023    7240    dsdred    36    

114

1С-ная магия

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

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

06.10.2023    19393    SeiOkami    46    

121

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

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

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

14.09.2023    13144    human_new    27    

76

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

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

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

28.08.2023    9694    YA_418728146    6    

146

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

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

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

20.08.2023    6651    sebekerga    54    

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


Все делается куда проще, не нужно запускать ракету такую как веб сервис.
Просто код, который должен быть в вложенной транзакции, изолируйте в фоновое задание.
rpgshnik; ovasiliev; mysm; Cmapnep; AneJIbcuH; +5 Ответить
2. Smirnov1980 7 09.07.21 05:36 Сейчас в теме
Конечно, можно и так, это второй вариант решения.
3. user621724_Dimav1979 404 09.07.21 06:40 Сейчас в теме
Ничего не понял, но было очень интересно.
vakham; asmuk; Interrupted; +3 Ответить
4. mysm 83 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 291 12.07.21 16:37 Сейчас в теме
Чтобы получить тексты сообщений, например для возврата веб-сервисом, достаточно воспользоваться функцией ПолучитьСообщенияПользователю
9. Smirnov1980 7 13.07.21 07:04 Сейчас в теме
(8) Спасибо за дельный совет. Тема именно "сообщений" приведена для примера.
Оставьте свое сообщение