Правила работы с транзакциями 1С

0. kuzyara 1529 27.09.22 11:47 Сейчас в теме
Список правил при работе с транзакциями из BSL Language Server и SonarQube 1C (BSL) Plugin. Переработка и осмысление материала.

Перейти к публикации

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. artbear 1428 01.12.22 22:08 Сейчас в теме
Хорошая подборка!
Значит, мы не зря придумывали и реализовывали эти правила.

Есть замечания
>ОписаниеОшибки() и КраткоеПредставлениеОшибки() не содержат текста строки, вызвавшей ошибку. Код может измениться к моменту анализа ошибки, и придется дополнительно исследовать, где же именно возникла ошибка.

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

именно наличие стека вызовов важно, а он есть только в ПодробноеПредставлениеОшибки, поэтому и нужно использовать данный метод.
ubnkfl; frkbvfnjh; Артано; user953800; PrinzOfMunchen; +5 Ответить
2. EliasShy 48 02.12.22 09:58 Сейчас в теме
Описания есть на соответствующих площадках, и лучше их из Сонара настроенного и смотреть. Правила живые, оптимизируются, дополняются. Ваша статья таким свойством не обладает.

Дополнения (ссылки на статьи) - полезные, но для внутреннего ресурса управления знаниями.

Зачем (ради чего) личные заметки публиковать на ресурсе?
4. artbear 1428 02.12.22 12:38 Сейчас в теме
(2) Считаю данную подборку полезной, проголосовал плюсом!

Напоминания разработчикам о полезном, обучение тех, кто не знает о важных особенностях.
18. EliasShy 48 06.12.22 10:07 Сейчас в теме
(4)
зном, обучение

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

Сколько подобных устаревших и вредных статей по оптимизации? Вячеслав устал уже опровергать предложенные методы.
3. ardn 474 02.12.22 11:22 Сейчас в теме
Отличная статья!
Krotov_Valery; +1 Ответить
5. kser87 2296 02.12.22 12:45 Сейчас в теме
трудно анализируемым ошибкам времени выполнения типа "В этой транзакции уже происходили ошибки." - анализируются средствами ТЖ.

Про ТранзакцияАктивна() - "я не понимаю, зачем это нужно, поэтому не используйте". Подход убийственный. ответ на это правильный такой: Правильно писать не "ОтменитьТранзакцию()", а

Если ТранзакцияАктивна() Тогда
ОтменитьТранзакцию()
КонецЕсли;

Всегда.

Почему? Потому, что 1С не поддерживает вложенные транзакции. Вы никогда не знаете наверняка, является ли ваша транзакция вложенной или ее саму куда-то вложили. никакие сонары это не показывают
6. gybson 02.12.22 14:52 Сейчас в теме
(5) Афигеть аргументация : "Потому что гладиолус"

А что взорвется, если эту ересь не писать?
8. kser87 2296 02.12.22 15:50 Сейчас в теме
(6) взорвется код если вызвать ОтменитьТранзакцию() вне активной транзакции. Такое бывает, когда базу дорабатывает большое количество людей.
9. пользователь 02.12.22 16:03
Сообщение было скрыто модератором.
...
11. nicxxx 247 02.12.22 16:41 Сейчас в теме
(8) Для этого есть тесты
EliasShy; +1 Ответить
12. kser87 2296 02.12.22 16:48 Сейчас в теме
(11) и код ревю и надо вообще смотреть когда вызываете чужие методы. На практике часто не работает по объективным причинам.
13. buganov 194 03.12.22 09:00 Сейчас в теме
(5)А еще лучше управлять исключительными ситуациями на том слое, на котором они возникли, и тогда ге придется ломать голову, а выше открыта транзакции или нет, есть ли там попытка или нет. Например, через проброс исключения наверх.
Общий модуль.ОбщийСервер.КакойтоМетод()
НачатьТранзакцию();
Попытка
    Док.Записать();
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;


И плевать, что там в вызывающем модуле, транзакции, попытка или еще что.
rozer; kuzyara; +2 Ответить
20. frkbvfnjh 720 06.12.22 14:51 Сейчас в теме
(13) Вот это вообще не понимаю зачем делать - делать в попытке, что бы не было исключения, и принудительно его (исключение) генерировать
22. frkbvfnjh 720 06.12.22 15:12 Сейчас в теме
(20) Для меня попытка исключение и транзакция вещи не совместимые - ты либо делаешь в транзакции, либо в попытке, как можно вообще смешивать это? А главное зачем?
23. buganov 194 06.12.22 18:14 Сейчас в теме
(20)чтобы обогатить данные об ошибке, например
27. gybson 08.12.22 11:04 Сейчас в теме
(20) Обработка исключения это не только * транзакции. Например там можно сделать запись в журнал и Отказ = Истина, прочие обработки потом пробросить его наверх
28. kuzyara 1529 08.12.22 11:41 Сейчас в теме
(27)
Например там можно сделать запись в журнал и Отказ = Истина, прочие обработки потом пробросить его наверх
вот как раз с записью в журнал в сломанной транзакции есть проблемы:
При обработке исключения в сломанной транзакции часто разумно писать диагностическую
информацию в журнал регистрации. При этом метод ЗаписьЖурналаРегистрации() неявно берет
представление от ссылки, используя кэш представлений ссылок, и помещает его
в поле "Представление данных" события журнала. Обращение к этому кэшу в сломанной
транзакции несет риск невосстановимой ошибки. (с) https://infostart.ru/1c/articles/1026771/
поэтому правильным считаю либо использовать СсылкаДляПередачиВЖурналРегистрации() из той статьи, либо писать ВызватьИсключение; // есть внешняя транзакция сразу после отмены транзакции (оставив работу по записи в журнал вызывающему методу) если внешняя транзакция конечно же есть
31. gybson 08.12.22 12:09 Сейчас в теме
(28) В журнал регистрации можно записать и просто строку с нужным видом события.
7. Sashares 31 02.12.22 14:52 Сейчас в теме
Ошибка в коде - должно быть КонецПопытки; - см.файл.
Прикрепленные файлы:
10. gybson 02.12.22 16:09 Сейчас в теме
Код, который начинает транзакцию, обязан завершить или откатить ее. В случаях когда метод НачатьТранзакцию() находится внутри блока Попытка-Исключение есть риск нарушения парности вызовов НачатьТранзакцию()-ЗафиксироватьТранзакцию(


Вот это что-то из области древних знаний, истоки которых утеряны. Как этот риск возникает? Почему? Никто уже не помнит.

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

Риск точно такой же, как если кто-то впишет код между началом транзакции и попыткой.
14. naf2000 05.12.22 17:39 Сейчас в теме
Да, пункт про НачатьТранзакцию() до попытки как-то слабо обоснован.
15. AndreyKN 05.12.22 23:07 Сейчас в теме
(14)Наверное, можно предположить обоснование следующее. А что, если выскочит ошибка на строке НачатьТранзакцию(), то, соответственно, попадаем в исключение, а там ОтменитьТранзакцию(), которую так и не смогли начать.

Правда не знаю, может ли возникнуть ситуация, чтобы НачатьТранзакцию() вызвало исключение.
24. buganov 194 06.12.22 18:18 Сейчас в теме
(15) Это из разряда фантастики. Как на открытии транзакции может завалиться, и при этом все еще пытаться обработать исключение?
16. kuzyara 1529 06.12.22 05:03 Сейчас в теме
(14) тоже так думаю, всегда писал в попытке - но есть ИТС https://its.1c.ru/db/v8std/content/783/hdoc и там в пункте 1.3 четко сказано что вне. Так что считаю за формальность
Прикрепленные файлы:
17. quazare 3004 06.12.22 08:35 Сейчас в теме
Понравилась вот эта фраза "Статья написана в личных целях для онбординга новых сотрудников, является частью соглашений по стилю кода."

т.е. приходит новый сотрудник - а ему еще и стиль кода вы устанавливаете?
19. naf2000 06.12.22 12:18 Сейчас в теме
(17) ну... Это вообще нормальные практики в командах
AllexSoft; +1 Ответить
21. frkbvfnjh 720 06.12.22 14:54 Сейчас в теме
Не понимаю, почему данный код считается ошибочным:
Процедура Пример2()
    НачатьТранзакцию();
    Попытка
        Метод();
    Исключение
        ОтменитьТранзакцию();
        Возврат;
    КонецПопытки;
    ЗафиксироватьТранзакцию(); // <-- Ошибка: вне попытки
КонецПроцедуры
Показать

Если после отмены транзакции мы вызываем Возврат - это как раз и есть гарантия того, что после отмены транзакции уже ничего не выполнится в методе. Разве нет? Или просто потому что код не такой красивый как хотелось бы автору данной рекомендации?
25. buganov 194 06.12.22 18:20 Сейчас в теме
(21)написание кода регламентирует стандартами разработки. Да, это не свод правил, но они предельно логичны, читаемы и определенно в большинстве своем оптимальны.
26. kuzyara 1529 07.12.22 05:31 Сейчас в теме
(21) такие конструкции сложно вкладывать друг в друга
29. gybson 08.12.22 12:06 Сейчас в теме
(21) Если в обработку исключения еще что-то не впишут
30. artbear 1428 08.12.22 12:09 Сейчас в теме
(21) да, код в целом нормальный.
фактически правило бсл лс здесь ложно срабатывает.
ИМХО проблема уже зарегистрирована в репозитории бсл лс
32. kuzyara 1529 09.12.22 06:21 Сейчас в теме
(30)
да, код в целом нормальный.
а такой код нормальный?
НачатьТранзакцию();
Попытка
    // нечто
    Если Истина Тогда
        ЗафиксироватьТранзакцию();
        Возврат;
    КонецЕсли;
    // Еще нечто
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки
Показать
33. artbear 1428 09.12.22 11:31 Сейчас в теме
(32) да, я считаю, что верный.

в некоторых случаях не удается упростить код и приходится в соседних ветках кода указывать ЗафиксироватьТранзакцию
34. apic 12 13.01.23 14:21 Сейчас в теме
Я что то не понял, а если я хочу совместить транзакции, попытку и запись в журнал регистрации, то какой паттерн то в итоге использовать?
Как правильно? Так:
НачатьТранзакцию();
Попытка
... // чтение или запись данных
ЗафиксироватьТранзакцию();
Исключение
// И запись события в журнал регистрации для системного администратора.
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ОтменитьТранзакцию();
... // дополнительные действия по обработке исключения
КонецПопытки;

Или так:
НачатьТранзакцию();
Попытка
    ... // чтение или запись данных
   
    ОтменитьТранзакцию();
Исключение
 ЗафиксироватьТранзакцию();
     // И запись события в журнал регистрации для системного администратора.
        ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
           УровеньЖурналаРегистрации.Ошибка,,,
           ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    ОтменитьТранзакцию();
    ... // дополнительные действия по обработке исключения
КонецПопытки;
Показать

Что первым делать, в журнал писать или транзакцию откатывать? Или все таки правильней получить описание ошибки в переменную, потом откатить транзакцию, а потом записать в журнал. Описание ошибки же в первую очередь нужно, но это противоречит тому, что в первую очередь нужно откатывать транзакцию... По сути все рекомендации бессмысленны, если их применять все вместе, а если применять их по отдельности, то тоже бессмысленны...
36. artbear 1428 13.01.23 14:47 Сейчас в теме
(34) правильно делать, как на сайте ИТС написано. Ссылка или в моих комментариях выше или в статье есть.
Там валидный пример, аналог вашего варианта №2
смотрите, шаблон-то простой

только зачем у вас Зафиксировать, а потом почти сразу же ОтменитьТранзакцию?
38. apic 12 13.01.23 15:59 Сейчас в теме
(36) Спасибо, да вижу, что во многих конфах используется вариант №2, но я думал, что вызов ОтменитьТранзакцию стирает описание об ошибке
40. artbear 1428 13.01.23 16:50 Сейчас в теме
(38) Повторю, ваш вариант 2 неверен, правильный вариант в стандартах
35. apic 12 13.01.23 14:26 Сейчас в теме
И объясните на кой черт использовать НСтр всегда и везде, если в параметры передаем только один язык? Я понимаю если бы было еще на английском, или это типа на будущее, что вдруг будем портировать на английский рынок и придется добавить на английском что ли?
37. artbear 1428 13.01.23 14:48 Сейчас в теме
(35) Если нет планов переходить на другой язык, конечно, НСтр можно не юзать.
Мне также не нравится его использование, только засоряет код и очень легко пропустить ошибки разного рода.
39. apic 12 13.01.23 15:59 Сейчас в теме
(37) Ну значит я все правильно понял, спасибо
Оставьте свое сообщение
Вакансии
Программист 1С
Оренбург
зарплата от 120 000 руб.
Полный день

Ведущий Инженер - программист 1С
Новокузнецк
зарплата от 100 000 руб.
Полный день

Программист 1C
Москва
Полный день

Главный специалист (Программист 1с)
Подольск
зарплата от 100 000 руб. до 110 000 руб.
Полный день

Ведущий инженер по тестированию
Санкт-Петербург
зарплата от 130 000 руб.
Полный день