Имя: Пароль:
1C
 
Попытка Исключение внутри транзакции
0 korstin
 
20.02.16
16:52
Задача: создать документ, попробовать провести, если не получится - просто сохранить.
Вроде бы все просто

Попытка
    Документ.Сохранить(РежимЗаписиДокумента.Проведение);
Исключение
    Документ.Сохранить(РежимЗаписиДокумента.Сохранение);
    ВызватьИсключение;
КонецПопытки;

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

Подскажите, как кошерно выполнить задачу. Спасибо
1 Wern
 
20.02.16
16:59
В момент проведения документ уже сохранен. Нет никакого смысла пытаться его еще раз записать.
2 mehfk
 
20.02.16
17:07
E,thb  ВызватьИсключение;
3 mehfk
 
20.02.16
17:07
*Убери
4 Drac0
 
20.02.16
17:17
(0) Убери транзакцию внешнюю.
5 korstin
 
20.02.16
17:18
(3) Мне нужно поднять исключение выше
(1) Если проведение документа вызвало ошибку, возникает исключение "Ошибка при вызове метода Записать" (по памяти пишу, могу ошибиться дословно) и документ не сохраняется
6 korstin
 
20.02.16
17:21
(4) Она мне нужна
7 mehfk
 
20.02.16
17:23
(5) Тогда чтоне так в (0).
8 korstin
 
20.02.16
17:26
(7) То, что нельзя пользовать Попытка Исключение внутри транзакции, как говорит 1С. А мне нужно пробовать провести документ. Если не проводится - просто сохранять. Как это сделать без использования Попытка Исключение?
9 mehfk
 
20.02.16
17:30
Ну тогда убери ВызватьИсключение.
10 lera01
 
20.02.16
17:31
Наверно, не Сохранить(...), а Записать()?
11 mehfk
 
20.02.16
17:32
А вместо него вставь Сообщить или ЗаписьЖурналаРегистрации
12 Builder
 
20.02.16
17:32
(8) Ну сохрани документы в своей транзакции, потом вне транзакции пытайся провести. Или я не понимаю что нужно ТС?
13 korstin
 
20.02.16
17:35
(10) Да, конечно же, Записать

(12) Это единственное решение, которое мне пришло. Но мне оно кажется некрасивым
14 Builder
 
20.02.16
17:52
(13) Вам шашечки или ехать?
15 ejikbeznojek
 
20.02.16
17:58
писать попытку внутри обработки проведения
если сработает исключение, то распроводить.

тоже самое что (12)  только двойная запись только когда всё плохо.
16 ejikbeznojek
 
20.02.16
17:59
+(15) ну или не распроводить
17 vde69
 
20.02.16
18:02
1с не поддерживает вложеные транзакции...
18 ejikbeznojek
 
20.02.16
18:10
Вот этот код отработал как надо))

Процедура ОбработкаПроведения(Отказ, РежимПроведения) Экспорт
    
    Попытка
        ч=Число("ваповарплд");
    Исключение
    Сообщить("ывплждвал");
    КонецПопытки;
19 ejikbeznojek
 
20.02.16
18:22
+

Процедура ОбработкаПроведения(Отказ, РежимПроведения) Экспорт
    
    Попытка
        ч=Число("ваповарплд");
        //какие-то проводочки
    Исключение
    Сообщить("ывплждвал");
    Проведен=Ложь;
    Записать(РежимЗаписиДокумента.Запись);
    Возврат;
    
    КонецПопытки;
20 mehfk
 
20.02.16
18:24
Смотри (2) и (9)
21 zak555
 
20.02.16
18:25
зачем попытку делать ?
22 Drac0
 
20.02.16
18:38
(13) Оно единственное. Иначе нельзя работать с транзакцией. Но можешь генерить фоновое задание на запись каждого документа. Вроде, оно в своей транзакции будет.
23 Drac0
 
20.02.16
18:39
+(22) только это уже будет пздц, а не транзакция.
24 korstin
 
20.02.16
18:50
(19), а также остальным (9), (19), (21). Понимаете, это все красиво, когда вызывается одна функция и все. А если у меня вызывается очередь функций, каждая из которых может вызвать ошибку?

Процедура ОбработатьОперацию()
Попытка
СоздатьДокумент();
Исключение
Сообщить(ИнформацияОбОшибке());
КонецПопытки;
КонецПроцедуры;

Функция СоздатьДокумент()
//Создание документа, в момент которого может возникнуть ошибка
СозданиеПодчиненныхДокументов();
//Если произошла ошибка во время создания подчиненных документов, главный документ тоже не должен быть создан
КонецФункции;

Функция СозданиеПодчиненныхДокументов()
//Здесь создаются, допустим, пять дополнительных документов. И здесь тоже может появиться ошибка
КонецФункции

Попытка
ОбработатьОперацию();
//И записать, допустим, регистр сведений только в том случае, когда все получилось
Исключение
Сообщить("Не получилось");
КонецПопытки

В "нормальных" языках это реализуется и код читается. Все, что я прочел здесь, показывает, что код будет выглядеть некрасиво.
(14) Я надеюсь, что вам никогда не доставался код, написанный абы как? Иначе вы бы не задавались вопросом про шашечки
25 Drac0
 
20.02.16
19:05
(24) сначала пойми, что есть транзакция, зачем она нужна и как ее использовать. Во всех языках программирования транзакция ведет себя одинаково. Вложенные транзакции Оракл и подобные ей костыли в других субд - нужны для другого класса задач.
26 Cyberhawk
 
20.02.16
19:23
"это все красиво, когда вызывается одна функция и все. А если у меня вызывается очередь функций, каждая из которых может вызвать ошибку?"
Обычно это решается взводом переменной Отказ, а каждый последующий блок кода выполняется в условии Если НЕ Отказ Тогда ...
27 Cyberhawk
 
20.02.16
19:24
Вместо Отказ можешь использовать любую переменную, если по какой-то причине такое имя не подходит (в контексте выполнения кода)
28 korstin
 
20.02.16
19:33
(25) Вы уж простите, но про транзакции я знаю очень многое, опыта хватает. try catch никогда не порождает неявных транзакций БД. А то, что RollbackToSavepoint вы называете костылями - не надо так.

(26)(27) Мне нравится. Видимо, это и есть решение. Спасибо

Спасибо всем за дискуссию. Хороших выходных и с наступающим
29 mehfk
 
20.02.16
19:56
Дружищще, а не кажется ли те что причина в том, что ты все-таки вызываешь исключение? Я, конечно, могу приехать к тебе лично, и насильно накормить тебя таблетками для стимулироания мозговой деятельности, но оно надо?
30 korstin
 
20.02.16
20:05
(29) Дружище, во всех языках поднимать наверх исключения это нормально. Я понимаю, что на этом форуме не нужно лить грязь на 1С, но вот отказываться от throw в блоке catch только из-за того, что создатели платформы не могли реализовать нормальную работу исключений - в этом нет моей вины, ведь так?
А твоя попытка показать агрессивность мне не нравится. Поэтому я не хочу продолжать этот разговор.
Еще раз спасибо и еще раз с праздниками. Ухожу с ветки. Пока
31 Drac0
 
20.02.16
20:11
(28) rollbacktosavepoint это не вложенная. Прямого управления транзакциями в 1С нет. Имхо, по причине большого количества бд, с которыми работает (в том числе своей файловой).

Именно поэтому исключение ломает транзакцию и можно сделать лишь полный rollback.
32 Armando
 
20.02.16
20:19
почему нельзя другим способом проверить приведется документ или нет?
33 mehfk
 
20.02.16
20:21
(30) Значит и в других языках/средах ты нуль. Бери лопату и махай, а пока летит отдыхай.
34 korstin
 
20.02.16
20:30
(32) Каким образом? Делать самому проверки на заполнение полей, остатки и прочее?
35 vde69
 
20.02.16
20:56
(30) при чем тут исключения??? читай (17)...

объясняю

транзакция 1
запись 1
транзакция 2
  запись 2
  ошибка ххх
конец транзакции 2
конец транзакции 1

по ошибке ххх существую 2 варианта
1. обе транзакции откатятся, но в этом случае транзакция 2 банально не нужна
2. транзакция 2 откатится (и запись 2), но запись 1 пройдет, при этом мы получаем что в рамках верхней транзакции часть действий откатилось а часть прошло, что мягко сказать не очень логично....
36 korstin
 
20.02.16
21:11
(35) Все потому, что Попытка в 1С стартует транзакцию. Причем Попытка не обязательно связана с записью в БД. Потому вы и рисуете в схеме транзакция 2.
37 Drac0
 
20.02.16
21:47
(36) Попытка не стартует транзакция, это бред, Исключение прерывает транзакция, что логично. Проблема  в том, что откат возможен только полный.

(35) Он хочет RollbackToSAvepoint.
38 vde69
 
20.02.16
22:09
(36) попытка - это всего лишь ловушка которая ловит необработанное сообщение об ошибке и блокирует его...

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

(35) 1с так не умеет
39 mikecool
 
20.02.16
23:05
Записать()
Попытка
  Провести


будь мужиком
40 Злопчинский
 
20.02.16
23:18
(39) ну.. в клюшках непроведение документа не вызывает исключения. в 8-ке - иначе?
41 Ma3eIIa
 
21.02.16
01:41
Делаешь так
НачатьТранзацию

Попытка
Провести
Исключение
Толькозаписать
Отмена транзакции.
Записываем
42 Ma3eIIa
 
21.02.16
01:49
Все равно что задачка

НачатьТранзакцию();
Док = Документы.ПлатежноеПоручениеИсходящее.СоздатьДокумент();
Док.Дата = ТекущаяДата();
Док.Записать();
ОтменитьТранзакцию();
Док = ?
Док.Дата = ?
Док.Ссылка = ?
Док.Ссылка.Дата = ?

какие значения будут вместо знаков вопросов?
43 su_mai
 
21.02.16
02:15
(0) Может проще всегда сохранять и если получиться проводить?
44 hhhh
 
21.02.16
05:57
(0) ну вот же, чего вы паритесь


Удачно = Истина;
Попытка
    Документ.Записать(РежимЗаписиДокумента.Проведение);
Исключение
    Удачно = Ложь;
КонецПопытки;

Если Удачно = Ложь Тогда
   Удачно = Истина;
   Попытка
       Документ.Записать(РежимЗаписиДокумента.Запись);
   Исключение
      Удачно = Ложь;
   КонецПопытки;
КонецЕсли;
Ошибка? Это не ошибка, это системная функция.