Имя: Пароль:
1C
1С v8
Как записать данные в транзакции и не потерять при отмене транзакции
0 realevgenius
 
08.01.22
11:08
Здравствуйте, уважаемые!

Столкнулся со своей некомпенентностью и отсутствием фантазии, так-сяк крутил код, гуглил, но не нашел ответа...

Ситуация: есть некая обработка, например, загрузка данных с сайта, с интернет магазина. Документы "Заказы клиента" создаются в транзакции, если что-то пошло не так в одном из документов, всё отменяется, документы не создаются, не записываются.
Мне нужно параллельно процессу создания документов создавать записи регистра сведений, например, какие-то комментарии по ходу создания Заказов. По итогу обработки, если что-то пошло не так, при отмене транзакции мои данные (регистр) тоже оказываются не записаны.
Как исхитриться так, чтобы мои записи регистра сведений сохранились?

Я конечно временно решил, записывая файл на диск, но это - тупо, хотелось бы в регистр сведений или куда-то в базу.
1 Смотрящий
 
08.01.22
11:09
Убери транзакцию
2 realevgenius
 
08.01.22
11:12
(1) Спасибо! Но транзакция необходима, убирать нельзя...
3 Фрэнки
 
08.01.22
11:17
Но ведь запуск процедуры в каком-то фоновом задании создает новый сеанс работы, который никак не связан с текущим
4 Смотрящий
 
08.01.22
11:21
(2) Накой она тебе ?
Прилетело с тырнет магазина три заказа
- транзакция - все три не загрузятся если есть проблемы хоть в одном
- нет транзакции - первый и третий загрузились, например, второй проблемный - нет

Сайт скорее всего перевышлет данные, или пишши в файлы только проблемный заказ для разбора

А то у тебя торговая деятельность останавливается вся...
5 Фрэнки
 
08.01.22
11:23
И еще вариант, который был и работал еще до УФ - подвязать Подписку к тому же событию, которое обрабатывается в транзакции. Подписка вне транзакции обрабатывается.
6 realevgenius
 
08.01.22
11:24
(4) Инет-магазин я привел для примера, поскольку, его все знают... Не нужно на нем зацикливаться...
Вопрос: как в транзакции, которая отменена записать часть данных (например, регистр сведений), а часть отменить (например, документы)
Сейчас решил пока так: создаю, записываю файл на дист, после транзакции его читаю, записываю регистр сведений... Но, понимаю, что это - тупо и убого, пока так работает в связи с моей косорукостью
7 Смотрящий
 
08.01.22
11:30
(6) В самой транзаеции не получиться.
Записывай данные в регистр после неудачной транзакции
8 hhhh
 
08.01.22
11:36
(6) в транзакции не получится такая эквилибристика.
9 nicxxx
 
08.01.22
11:41
(0) Элементарно. Пиши через http-сервис, поднятый в этой же базе. Будет небыстро, медленнее, чем в текстовый файл. Но зато как ты хочешь - в базу.
10 nicxxx
 
08.01.22
11:42
(8) Не надо торопиться с выводами.
11 realevgenius
 
08.01.22
11:51
(7) Да, записать после неудачной или удачной транзакции - это понятно.
Но транзакция запускается в самой верхней процедуре откуда запускаются куча процедур и функций, мне надо писать что происходит в них параллельно...
Транзакция может быть удачная или нет - этого заранее не знаешь.
Можно процедуры сделать функциями или передавать параметр и тащить все из всех процедур наверх, в процедуру, откуда начата транзакция и уже там записывать в регистр - это все понятно, но, мне кажется, тоже не очень умно...
12 Смотрящий
 
08.01.22
11:57
(11) Перед началом транзакции пихни структуру, массив или как ты там сделаешь в которой будешь отражать нужные данные если транзакция не закроется, ну и таскай между функциями/процедурами. При выходе если все нормально - сбрасывай эту структуру. Нет - закрывай транзакцию и со структуры пиши данные
13 realevgenius
 
08.01.22
12:02
Вопрос в том, что я, возможно, не умею с транзакциями работать, и может быть просто не знаю как это сделать: часть данных сохранять (Записи регистра), а часть отменять (Документы). Или это в принципе не реально?
14 realevgenius
 
08.01.22
12:06
(12) А можно как-то объявить какую-то глобальную переменную, которая будет массивом структур, доступная в любых модулях и ее заполнять? В принципе, наверное, можно сделать параметр сеанса - Строковую переменную и туда писать...
15 Смотрящий
 
08.01.22
12:07
(14) Можно. Разрешаю.
16 realevgenius
 
08.01.22
12:17
В общем, приходим к выводу: в транзакции нельзя записать часть данных, часть сохранить.

Всем - спасибо!
17 ДенисЧ
 
08.01.22
12:18
(16) Логично. На то она и транзакция. Если ОЧЕНЬ надо - пиши во внешний файл.
18 vde69
 
08.01.22
12:41
сначала получай данные и пиши их не в документ а в регистр (в регистре делаешь реквизит с типом хранилищезначений и в него фигачишь не сохраненный объект "документ"),

при необходимости регистр очистить

далее уже делаешь как тебе нужно, или в транзакции создаещь документы из регистра или нет...
19 SuperMario
 
08.01.22
13:26
(0)  а почему журнал регистрации не рассматриваете? И записи останутся (что ест ь правильно) и вывести интерактивно можно  с отбором.
20 SuperMario
 
08.01.22
13:29
>> например, какие-то комментарии по ходу создания Заказов

Зачем вам это "барахло" хранить в БД? Не раз нарывался на толстозадую БД и высянялось, что самая загруженная таблица-это рег. сведений, по типу Вашего.
21 H A D G E H O G s
 
08.01.22
13:39
(0) ФоновоеЗадание
22 mistеr
 
08.01.22
13:45
(0) Подробнее, пожалуйста. Есть заказ, есть комментарии к нему. Если заказ не пришел, а комментарии пришли, нафиг они нужны? А если нужны, на что они ссылаются?
23 realevgenius
 
08.01.22
13:50
(20) Мне это барахло - не зачем... Сотрудникам надо историю создания документов обработкой... Пример с загрузкой заказов с сайта - это просто пример
24 realevgenius
 
08.01.22
13:51
(22) Пример с загрузкой с сайта - это просто пример, не нужно на нем зацикливаться...
25 Смотрящий
 
08.01.22
13:53
(23) Опиши плз что они делают имея данную информацию, чисто спортивный интерес
26 mistеr
 
08.01.22
13:55
(24) Тогда давай реальный пример, если хочешь реальных советов.
27 realevgenius
 
08.01.22
13:57
(18) Данные ни откуда не получаю... Пример с загрузкой с сайта - это просто пример... Надо создавать, проводить кучу документов, писать некую таблицу по ходу дела, таблицу должны анализировать сотрудники, делать отборы по разным полям и тд
28 realevgenius
 
08.01.22
14:00
(24) Реальный пример, кратенько - адресный склад, подбор с ячеек, создание цепочки документов ордер - отбор - реализация - счфактура - трансп накладная по правилам, методологии предприятия, здесь же печать комплекта и рассылка комплекта получателям.
29 SuperMario
 
08.01.22
14:00
(23) Я и предлагаю журнал. Обрати внимание,  как в типовых решениях отображается история обменов данными (к примеру).
30 realevgenius
 
08.01.22
14:03
(29) Если этот журнал в виде отчетов будут шурудить несколько пользователей, все повиснет, ну и они курить будут сидеть. Регистр сведений - отличная штука... и оно сейчас работате... просто думал, в транзакции как-то можно часть данных записать независимо от результата выполнения.
31 SuperMario
 
08.01.22
14:03
(28) замечательно. И что фиксировать хотите? Транзакционные ошибки и отображать их  пользователю?
больше информации...
32 Фрэнки
 
08.01.22
14:04
(29) хреновенький способ, т.к. в нагруженных базах ЖР хранят не более суток
33 Фрэнки
 
08.01.22
14:04
(30) тебе же несколько раз сказали об использовании Фоновых заданий
34 SuperMario
 
08.01.22
14:05
(32) зачем в крайности бросаться? Если так рассуждать, что ЖР можно вообще не вести.
35 realevgenius
 
08.01.22
14:09
(33) Да, ЖР - вообще шляпа... Как это сделать в фоновых заданиях и причем здесь они - не представляю...
36 Фрэнки
 
08.01.22
14:15
(34) ну я его регулярно просматриваю, но он хранится только до конца текущих суток. Ошибки попадаются. Просматривать его нужно. А вот с пользовательской точки зрения - история версий.
Которую тоже можно очищать, когда она слишком распухает.
37 Фрэнки
 
08.01.22
14:20
(35) Фоновое задание в новых БСП можно стартовать. С параметрами. Через параметры заталкивать в задание инфу. При своем выполнении задание полученные данные из параметров сможет записать в базу. Исполнение фонового задания происходит в отдельном сеансе и транзакция у него будет своя собственная, если она вообще будет.

Может и не самый быстрый способ, но вполне себе для конф на новых БСП типовой.

А вот еще интересно было упомянуто использование http-сервиса. Причем, этим сервисом можно и не обязательно в свою текущую базу писать, но можно и в свою же. Хотя там тоже будет отрабатывать фоновое задание :-) Только способ его запуска будет такой вот странный : левой пяткой за правым ухом, если хотите.
38 mistеr
 
08.01.22
14:22
(28) Ты объясни подробнее, зачем пользователям анализировать данные по отмененным транзакциям?

Это они проверяют, что напортачила твоя обработка? Другими словами, тестирование на проде?
39 realevgenius
 
08.01.22
14:34
(38) Я, вроде не писал, что пользователям надо анализировать данные по отмененным транзакциям.
Надо анализировать ход обработки, как она принимает решения что откуда брать и куда класть, в какой момент разбивать упаковки и т.д. Это надо и для успешных транзакций и для неуспешных, если например, остатки кривые в разных контурах учета или не провелась реализации в связи с нарушением оплаты или еще почему.
40 realevgenius
 
08.01.22
14:39
(37) Понял, интересно... Спасибо за информацию!
41 mistеr
 
08.01.22
14:39
(39) Не лучше ли все это писать в доп. реквизиты конкретных документов?

А технически — сохраняешь данные в каком-нибудь буфере в памяти (Массив или другая коллекция). Если в основной транзакции ошибка, откатываешь ее и в отдельной транзакции пишешь свои данные.
42 SuperMario
 
08.01.22
14:44
(39)

>>остатки кривые в разных контурах учета или не провелась реализации в связи с нарушением оплаты или еще почему.

Колхоз 90 lvl так делать!
43 RetardedToBoot
 
08.01.22
15:31
(0) я для подобного, добавил параметр сеанса, в который складываю список нужных данных в виде списка структур. И после, по обработке ожидания, которую периодически вызывает клиентское приложение, скидываю записи в регистр. И при завершении дозаписываются оставшееся. Но у меня это не учетные данные, а что-то вроде дополнительного логирования событий для последующих отчетов.
44 vde69
 
08.01.22
16:11
кто мешает накапливать сообщения и записывать их ПОСЛЕ основной транзакции ???
45 SuperMario
 
08.01.22
16:25
(44) а есть еще какие-то транзакции, кроме основной?
46 realevgenius
 
08.01.22
16:38
(44) Никто не мешает... можно... Просто, неудобно, ибо см (11)
47 vde69
 
08.01.22
18:42
(46) зачем все тащить через процедуры? сохраняй в глобальную переменную, или даже можно в параметр сеанса...
48 Жан Пердежон
 
08.01.22
19:34
(11) Значит тебе не в транзакции надо это всё запускать (по определению)
Всё остальное - параметры сеанса / фоновые задания / и т.д. - костыли
49 АНДР
 
08.01.22
19:41
(0) В Исключении, перед ОтменитьТранзацкию(), выгрузи нужные записи во временную(е) таблицу, после отмены транзакции загрузи и запиши снова.
50 ejikbeznojek
 
08.01.22
20:49
(0) При отмене транзакции отменяются действия в базе данных, но не отменяются действия с памятью. Пиши в транзакции записи в массив. А после окончания транзакции из массива в РС.
51 ejikbeznojek
 
08.01.22
20:51
(50) не увидел предыдущие ответы. Но вариантов то особо нет.
52 pechkin
 
08.01.22
21:04
Сделай процедуру ЗаписьВЛог(Текст)
Вызывай
ФоновыеЗадания.Выполнить("записьВЛог", Текст)
Пс. Код примерный
53 ДедМорроз
 
09.01.22
00:36
Вообще-то,сначала данные с сайта получают и пишут во временное хранилище,а после успешной записи сайту сообщают,что получено - если во временное хранилище не записалось,то сайт должен высылать повторно.
Временное хранилище - это или регистр или файл.
Потом начинаем обрабатывать,то есть выполняется создание документов,проведение и т.п. и для каждого документа - отдельная транзакция,после которой во временном хранилище метим запись,что она обработана - или удаляем.
Если не обработана,то откат транзакции и запись в хранилище ошибки выполнения,чтобы потом оперативно можно было все ошибочные документы увидеть.
54 Cyberhawk
 
09.01.22
01:55
Можно перед записью в РС разорвать внешнюю транзакцию (Пока ТранзакцияАктивна() ОтменитьТранзакцию(); КонецЦикла).
После этого - опционально, при необходимости - восстановить счетчик вложенности и признак поломки до разрыва (чтоб не нарушить логику вызывающего кода, если она опирается на это).
55 ДедМорроз
 
09.01.22
12:31
(54)это полная подстава.
Представь - у тебя код выполняет какое-то действие,а в конце подтверждает транзакцию и ожидает,что все данные записались,а нет,оказывается,кто-то внутри подменил транзакцию и в ней записалось совершенно не то,что ожидалось.
56 NorthWind
 
09.01.22
18:30
(0) по-моему, вы очень усложняете. Транзакцию нужно рассматривать как атомарную операцию - или залетело все, или ничего. Никаких наполовину. Поэтому если вы хотите пробовать еще раз, хранить данные нужно не в базе. Файл вполне рабочий вариант, но можно рассмотреть и какие-нибудь переменные.
57 Cyberhawk
 
09.01.22
22:04
(55) "а в конце подтверждает транзакцию" // Нет. Я ведь написал: "опционально, при необходимости - восстановить ... признак поломки до разрыва".
58 pechkin
 
09.01.22
22:08
(55) автотранзакцию (та что от проведения) таким способом не отменишь