Имя: Пароль:
1C
1С v8
v8: Использование транзакций в попытке
0 DirecTwiX
 
13.02.13
12:15
Вот код. Он нормально отработает? Или всегда обязательно фиксировать/отменять транзакцию вручную?

Попытка
...
НачатьТранзакцию;
...
Если А То Вызвать исключение "Возникли ошибки, все изменения отменены";
...
ЗафиксироватьТранзакцию;
Исключение
Сообщить(ОисаниеОшибки());
КонецПопытки
1 Maxus43
 
13.02.13
12:19
зачем вобще это вот?
В попытке вызывай исключение - и так "ОтПопытится"
2 mikecool
 
13.02.13
12:19
откат любой "вложенной" транзакции, которой нет, влечет откат всей транзакции
3 Maxus43
 
13.02.13
12:20
(1) хотя нет, не отпопытится. запись пройдёт успешно например. Попытка - не совсем транзакция
4 бомболюк
 
13.02.13
12:21
я вот так делаю:
НачатьТранзакцию();
Попытка
 // что то там...
 ЗафиксироватьТранзакцию();
Исключение
 ОтменитьТранзакцию();
 ВызватьИсключение; // ну или Сообщить(ОписаниеОшибки());
КонецПопытки;
5 DirecTwiX
 
13.02.13
12:27
(3) Там внутри попытки транзакция..
(4) Тоже так делал, но в первой части попытки не всегда работа  с базой..
6 Jolly Roger
 
13.02.13
12:46
(0) явная фиксация/откат, не полагаясь на систему, позволит избежать неожиданных сюрпризов...
7 бомболюк
 
13.02.13
12:48
(5) думается мне что все операции не с базой лучше вынести в другой блок "Попытка - Исключение - КонецПопытки"
8 Maxus43
 
13.02.13
13:01
(5) это не совсем транзакция.
Попытка
Объект1.записать();
Объект2.Записать();
Исключение
....

Даст например щаписать Объект1, даже если Объект2 записать не получилось.
9 Darklight
 
13.02.13
13:13
Уважаемые, если у Вас во время транзакции произойдёт ошибка, то тут два варианта
1. Ошибка так или иначе будет связана с работой информационной базы, т.е. с данными - транзакция отменится автоматически с соответствующим состоянием в момент возникновения ошибки (в секции "Исключение" транзакция уже будет закрыта, но её повторная отмена не приведёт к ошибке, а вот попытка дальше обращаться к данным - приведёт к возникновению "в данной транзакции уже были ошибки" - это состояние сбросится как только завершится выполняемый вызов (т.е. интерфейс раз блокируется) или не будет начата новая транзакция, или вызвана отмена транзакции. Если обработки исключения не будет - то выполняемый вызов завершится сразу после выдачи сообщения об ошибки.
2. Если ошибка не будет связана с данными ИБ, то транзакция в попытке исключения останется активной (а вне попытки автоматически отменится, как в предыдущем пункте) - её отмена произойдёт либо при вызове отмены транзакции, либо при завершении выполняемого вызова (выхода в интерфейс). До этого момент при обращении к данным транзакция будет активна.
10 Darklight
 
13.02.13
13:19
Помните, что бывают вложенные транзакции (в т.ч.) неявные - ошибка при обработке данных ИБ во вложенной транзакции - автоматически отменяет всю иерархию вызовов транзакций (в состоянии ошибки), независимо от того, будет ли она где-то перехвачена. Обработанная ошибка "вне данных" не отменяет транзакцию.
Вызов исключения через "ВызыватьИсключение" не вызывает ошибку обработки данных и не отменяет транзакцию автоматически, если такое исключение будет перехвачено в попытке исключений.
11 DirecTwiX
 
13.02.13
13:26
(8) Перечитай первое сообщение
(10) Спасибо. Вопрос по второму пункту из (9). Возникла ошибка не с данными ИБ, попадает в исключение, транзакция активна. Её ещё можно зафиксировать, если я правильно понял?
12 Maxus43
 
13.02.13
13:28
(11) по сабжу ответ в (4), это есть правильно
13 Darklight
 
13.02.13
13:31
Ещё используют такой паттерн

ЕстьТранзакция = Ложь;

Попытка
//Код до транзакции

Если необходима транзакция Тогда
  НачатьТранзакцию();
  ЕстьТранзакция = Истина;
 
  //Код в транзакции
 
  Если нужно вызвать исключение Тогда
     вызватьисключение "Исключение";
  КонецЕсли;
КонецЕсли;

Если ЕстьТранзакция Тогда
  ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
Если ЕстьТранзакция Тогда
  ОтменитьТранзакцию();
КонецЕсли;
Конецпопытки;
14 DirecTwiX
 
13.02.13
13:32
(13) Была такая мысль, но не хотел заводить ещё перемнную)
А что с (11)? Я правильно понял?
15 Darklight
 
13.02.13
13:35
(11)Можно зафиксировать.
(12)Там(4) как раз немного другое
(13) Забыл добавить, что после фиксации или отмены транзакции еёщ лучше сбросить флаг ЕстьТранзакция=Ложь
А в конце обработки исключения можно перевызвать исключение "Вызватьисключение;". Этот паттерн очень хорош во вложенных транзакциях.
16 Darklight
 
13.02.13
13:42
Отмена транзации через "ОтменитьТранзакцию" - так же отменяет все транзакции по вложенной иерархии транзакций (но по каждому вложению, его в приницпе можно повторно вызывать столько же раз, сколько была явно открыта транзакция). В этом случае в паттерне (13)  флаг "ЕстьТранзакция" может бытьобщим на всю иерархию вложенных транзакций, но это не обязательно.
Неявные транзакции обычно все связаны с данными, например, запись документа, в этом случае обычно выставляется отказ (внутри обработки записи) и вызов метода записи генерирует ошибку - это маркер, что транзакции больше нет.
17 DirecTwiX
 
13.02.13
13:47
Спасибо
Ошибка? Это не ошибка, это системная функция.