Имя: Пароль:
1C
1С v8
как вы оформляете транзакции?
0 GANR
 
28.09.15
12:49
1. Способ 2 100% (3)
2. Способ 1 0% (0)
Всего мнений: 3

//Способ 1:
НачатьТранзакцию();
Процедура1();
ЗафиксироватьТранзакцию();

//Способ 2:
НачатьТранзакцию();
Попытка  
  Процедура1();  
  ЗафиксироватьТранзакцию();
Исключение
  ОтменитьТранзакцию();
  ВызватьИсключение;
КонецПопытки;
1 Волшебник
 
модератор
28.09.15
12:50
А какая разница-то?
2 ДенисЧ
 
28.09.15
12:50
Зависит от потребностей
3 GANR
 
28.09.15
12:51
(2) можешь дать пример потребности где может понадобиться "способ 1"?
4 PR третий
 
28.09.15
12:51
(0) А что вы используете, процедуры или функции?
5 ДенисЧ
 
28.09.15
12:52
(3) Могу.
Если  я гарантированно знаю, что ошибок не будет, то зачем мне попытки?
6 GANR
 
28.09.15
12:52
(5) исходим из того, что знать невозможно
7 PR третий
 
28.09.15
12:53
(3) А ты всегда используешь при выполнении любого кода попытки?
8 ДенисЧ
 
28.09.15
12:53
(6) Значит, у тебя плохой код, если ты не знаешь, что в нём может произойти
9 GANR
 
28.09.15
12:54
(7) тогда, когда невозможно знать как поведет себя код
10 alexpr111
 
28.09.15
12:54
Что в первом случае будет с уровнем вложенности транзакций? Будет ли активна неявная транзакция сеанса?
11 PR третий
 
28.09.15
12:55
(9) Ну то есть ты сам сейчас ответил на вопрос в (0).
12 Лефмихалыч
 
28.09.15
12:56
(0) если способ 1 исключает использование попыток, то такой способ нахрен ни к чему не годится, выкинь его скорей
13 GANR
 
28.09.15
12:57
(8) Вот представь - ты вызываешь процедуру, которую писали другие разработчики на другом языке в КОМ-объекте каком-то. Ты можешь знать что там внутри?
14 Mashinist
 
28.09.15
13:00
(3)

НачатьТранзакцию();
Если Функция1() Тогда
ЗафиксироватьТранзакцию();
Иначе
ОтменитьТранзакцию();
КонецЕсли;
15 Enterprise
 
28.09.15
13:02
"Не всякая ошибка приводит к невозможности продолжения выполнения и фиксации транзакции, а именно ошибка базы данных. Исключения, не имеющие отношения к ошибкам базы данных, никакого влияния на возможность продолжения выполнения транзакции не оказывают."

Т.е. в первом способе если будет ошибка не связанная с БД, то транзакция закроется, во втором будет корректно отработана такая ситуация.

Способ 2
16 Гёдза
 
28.09.15
13:07
Зачем нужна транзакция, если нет работы с БД.
А если она есть то всегда может быть ошибка
17 Гёдза
 
28.09.15
13:08
Вопрос, что лучше писать попытки внутри процедуры или снаружи?
Тут на вкус и цвет. Никаких рекомендаций на эту тему нет
18 vhl
 
28.09.15
14:28
Попытка
            
        НачатьТранзакцию();
            
        
            
        ЗафиксироватьТранзакцию();
            
    Исключение
        
        Сообщить(НСтр("ru = 'Ошибка: '; en = 'Error: '")+ОписаниеОшибки());
        Если ТранзакцияАктивна() Тогда
            ОтменитьТранзакцию();
        КонецЕсли;
            
    КонецПопытки;
19 GANR
 
29.09.15
22:45
(15) Единственный осмысленный ответ. Проводил эксперименты

НачатьТранзакциию();

ДокОбъект1.Записать();
а = 1 / 0; //здесь преднамеренно делаем ошибку
ДокОбъект2.Записать();

ЗафиксироватьТранзакцию();

В результате ДокОбъект1 остался записанным (хотя ЗафиксироватьТранзакцию() не было.
20 ssh-2013
 
29.09.15
23:01
(19) записи не может быть, т.к нет фиксации транзакции
21 ssh-2013
 
29.09.15
23:03
по жр посмотри и увидишь, что транзакция отменена
22 ssh-2013
 
29.09.15
23:04
а вот если деление на 0 обернуть в попытку, то транзакция зафиксируется, т.к. ошибка была не связана с записью в бд
23 DexterMorgan
 
29.09.15
23:32
24 EvgeniuXP
 
30.09.15
00:44
(13) вот представь, ты залез к ней по COM, а там сидит бухгалтер и воет от того, что ты залез и твоя процедура/функция выполняется долго, а ей срочно надо зайти в монопольный режим.
25 EvgeniuXP
 
30.09.15
00:46
(17) если твоя процедура содержит миллион циклов - то грошь твоей транзакции :)
26 EvgeniuXP
 
30.09.15
00:50
Записано = Ложь;
Пока Не Записано Цикл
    Попытка
        НачатьТранзакцию();
        Данные.Записать();
        ЗафиксироватьТранзакцию();
        Записано = Истина;
    Исключение
        ОтменитьТранзакцию();
    КонецПопытки;
КонецЦикла;

пример плохой :)
27 Zamestas
 
30.09.15
00:51
(25) В (0) Собственно речь, о том - ловите ли Вы мышей в транзакциях или нет.
28 EvgeniuXP
 
30.09.15
00:51
не говоря уже об этом:

НачатьТранзакцию();
Записано = Ложь;
Пока Не Записано Цикл
    Попытка
        Данные.Записать();
        Записано = Истина;
    Исключение
    КонецПопытки;
КонецЦикла;
ЗафиксироватьТранзакцию();
29 mistеr
 
30.09.15
09:14
(28) Еще хуже.
30 GANR
 
30.09.15
18:49
(21) Ой-ёй. Точно - попробовал поменять реквизит "Комментарий" - не сохранился. (19) - неверно.
31 bolobol
 
30.09.15
19:03
Записано = НЕОПРЕДЕЛЕНО;
Пока Записано = НЕОПРЕДЕЛЕНО Цикл
    Попытка
        НачатьТранзакцию();
        Данные.Записать();
        ЗафиксироватьТранзакцию();
        Записано = Истина;
    Исключение
        ОтменитьТранзакцию();
        Если Вопрос("Произошла ошибка, повторить?", ДАНЕТ, 5) = НЕТ Тогда
            Записано= ложь;
        КонецЕсли;
    КонецПопытки;
КонецЦикла;
32 bolobol
 
30.09.15
19:05
Записано = -30;
Пока Записано Цикл
    Попытка
        НачатьТранзакцию();
        Данные.Записать();
        ЗафиксироватьТранзакцию();
        Записано = 0;
    Исключение
        ОтменитьТранзакцию();
    КонецПопытки;
    Записано= Записано +1;
    Спааать3секунды();
КонецЦикла;
33 bolobol
 
30.09.15
19:08
+ обработчики возврата от ОписаниеОшибки() можно прикрутить:
Если Найти(Ош, "уникал")...
Если Найти(Ош, "блокировки")...
Если Найти(Ош, "нет интернета")...
34 kiruha
 
30.09.15
19:13
В (18) правильный ответ.
Никто не заметил что ли ?
35 kiruha
 
30.09.15
19:15
Хотя есть ньюанс - вложенные транзакции.
Внешняя может быть активна
36 viraboy
 
30.09.15
20:05
Как вы узнаете где произошла ошибка в процедуре или при фиксации транзакции. Моветон две функция в один перехватчик пихать
37 Злопчинский
 
30.09.15
20:53
Меня больше интересует вопрос:
а с какого хз вы решили что без ошибок отработает НачатьТранзакцию? может споткнеться как раз здесь...? если база стоит в транзакции..? или я неправильно понимаю?
38 Злопчинский
 
30.09.15
20:54
Попытка
        НачатьТранзакцию();
        Данные.Записать();
        ЗафиксироватьТранзакцию();
        Записано = 0;
    Исключение
        ОтменитьТранзакцию();
    КонецПопытки;

...и что будет при попытике отменить неактивную транзакцию?
39 spectre1978
 
30.09.15
23:12
Я бы НачатьТранзакцию () обычно делаю вне попытки. А в остальном

Способ 2
40 Злопчинский
 
01.10.15
00:16
хм...я бы начало и конец транзакции вообще внутри дочерней вызываемой процедуры делал, а наружу возвращал флаг успешности\неуспешности...???
41 ЧеловекДуши
 
01.10.15
06:48
(0)  А у мну свой вариант

Попытка
        НачатьТранзакцию();
        Данные.Записать();
        ЗафиксироватьТранзакцию();
        Записано = 0;
    Исключение
       Если ТранзакцияАктивна() тогда
        ОтменитьТранзакцию();
       Конецесли;
    КонецПопытки;
42 kiruha
 
01.10.15
12:46
(41)
Так а если вдруг вложенная ?
43 Buster007
 
01.10.15
12:51
(42) вложенная что?
44 kiruha
 
02.10.15
14:40
Транзакция в транзакции.
Внутренняя откатилась, но внешняя то еще активна
45 rozer76
 
02.10.15
14:52
только так

Способ 2
46 rozer76
 
02.10.15
14:53
(15) +1
47 Timon1405
 
02.10.15
15:13
(42) говорит что в (41) не
Если ТранзакцияАктивна() Тогда
а
Пока ТранзакцияАктивна() Тогда
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший