Имя: Пароль:
1C
1C 7.7
v7: Попытка и транзакция...
,
0 Злопчинский
 
21.10.11
15:25
Мусолилось уже... однако..
.
В цикле
- создаем документ1;
- ссылку на него прописываем в документ2
КонецЦикла
.
док1 и док2 - д.б "согласованы" - изменены или неизменены (при проблеме) одновременно - итого работаем в транзакции..., транзакцию пихаем внутрь цикла, сбой с документами внутри цикла не должен прервать обработку в цикле других доков...
.
но есть тонкостти с попытками и транзакциями...?
.
пишу типа так (в порядке дежурного бреда)
.

Цикл ы=1 По КолвоДоков

 Док1.Новый();
 Попытка
    НачатьТранзакцию();
    Док1.Записать();
 Исключение
   Попытка //могло дать сбой как на записи дока, так и на начале транзакции
               //если сбой на записи дока - тогда отменяем транзакцию
               //если сбой на начале транзакции - транзакция неактивна
               //и текущая вложенная попытка скушает ошибку отмены неактивной транзакции
         ОтменитьТранзакцию();
       Исключение
       КонецПопытки;
           
       Сообщить("Не удалось сформировать Док1","!");
       Продолжить; //цикл по докам
    КонецПопытки;    
//
// тут в цикле работаем с Док2 - пишем в него ссылку на док1
   Док2.СсылкаДок1 = Док1.ТекущийДокумент();
   Попытка
      Док2.Записать();
   Исключение
      ОтменитьТранзакцию();
   КонецПопытки;
КонецЦикла;
.
или я сильно намудрил...? можно проще как-то..?
.
Цикл СчетчикДоков
  Док1.Новый();
  НачатьТранзакцию();
    Док1.Записать();
    Док2.СсылкаДок1=Док1.ТекущийДокумент();
    Док2.Записать();
  ОтменитьТранзакцию();
КонецЦикла;
.
сломаться ведь может как на записях доков так и на начале самой транзакции - юзверю надо выдать инфосообщение при этом, НЕ ПРЕРЫВАТЬ цикл и уйти на следующую итерацию...
.
???????????????????????
1 Злопчинский
 
21.10.11
15:28
такой же вариант не прокатит:

НачатьТранзакцию();
 Попытка
    Док1.Записать();
 Исключение
    ОтменитьТранзакцию();
    Продолжить; //на след.итерацию цикла
 КонецПопытки;

 Док1.СсылкаДок1=Док1.ТекущийДокумент();
 Попытка
    Док2.Записать();
 Исключение
    ОтменитьТранзакцию();
    Продолжить; //на след.итерацию цикла
 КонецПопытки;

..
???????????????
..
2 Злопчинский
 
21.10.11
15:29
только не спрашивайте и не ругайте про записи ссылок - мопед не мой, чинить бесполезняк.. главное чтобы хотя бы с горы катился пока не упадет...
;-)
3 vde69
 
21.10.11
15:35
если ты делаешь транзакцию которая не откатывается внутреней попыткой то она должна начинася ДО попытки и фиксироватся/откатыватся после.

кроме того попытка в обработчие "исключение" - это шедевр!!!

я-бы делал в таком духе

степ = 0;
 НачатьТранзакцию();

 Попытка
    Док1.Записать();
степ = степ  + 1;
 Исключение
степ = -10000;

 КонецПопытки;  


 Попытка
    Док2.Записать();
степ = степ  + 1;
 Исключение
степ = -1000000;

 КонецПопытки;  
если степ > 0 тогда
зафиксироватьтранзакцию();
иначе
ОтменитьТранзакцию();
конецесли
4 Ёпрст
 
21.10.11
15:41
фл=0;
   Пока фл=0 Цикл
       НачатьТранзакцию();
       Попытка
           Док.Записать();
           ЗафиксироватьТранзакцию();
           фл=1;
       Исключение
           Попытка
               ОтменитьТранзакцию();
           Исключение
           КонецПопытки;
       КонецПопытки;
   КонецЦикла;
5 Злопчинский
 
21.10.11
15:55
(3) и (4)
весь вопрос в том - рухнет ли цикл обработки документов или в (4) цикл фл=0
если проблема вылезет ПРИ ПОПЫТКЕ ОТКРЫТЬ ТРАНЗАКЦИЮ...???????
6 vde69
 
21.10.11
16:03
(5) не закладывайся на обработку создания транзакции, это глупо....

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

по этому если у тебя в памяти есть объект ошибки (без разницы где он получен) то зафиксировать транзакцию не удастся
7 Злопчинский
 
21.10.11
16:14
(6) > по этому если у тебя в памяти есть объект ошибки (без разницы где он получен) то зафиксировать транзакцию не удастся
- если обработка исключения удалит этот "объект",
то !!вне попытки!! транзакция успешно зафиксируется - даже при ошибке с документом.. - так?
8 Злопчинский
 
21.10.11
16:14
> не закладывайся на обработку создания транзакции, это глупо....
- тут не понял что ты имеешь в виду?
9 Злопчинский
 
21.10.11
16:16
вопрос пока остался:
.
рухнет ли цикл обработки документов или в (4) цикл фл=0
если проблема вылезет ПРИ ПОПЫТКЕ ОТКРЫТЬ ТРАНЗАКЦИЮ..
- я так думаю что рухнет... - а этого допустить нельзя...
10 Ёпрст
 
21.10.11
16:19
(9) С какой радости ?
будет долбится до победы.
11 vde69
 
21.10.11
16:21
(7) да совершенно верно, только не забывай что при проведении документа есть неявная транзакция, и хотя 1с не работает с вложеными транзакциями то будет следующее.

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

Единственный момент - возможно сообщение на подобии "транзакция не активна", но это зависит от модуля проведения документа и где возникла ошибка, если программно через "отказ" то все будет хорошо, а если на системном уровне (например блокировка) - то все плохо.
12 Ёпрст
 
21.10.11
16:21
ё моё.. такие вещи проверяются на раз два в любой базе .
13 Злопчинский
 
21.10.11
16:29
(10) ок!
(11) с проведением по идее надо типа так (хотя в данном вопросе у меня проведения нет)

НачатьТранзакцию();
Если Док.Провести()=0
Тогда //внутрення транзакция проведения закрылась уже
  ОтменитьТранзакцию();
Иначе
  ЗафиксироватьТранзакцию();
КонецЕсли;

- в таком виде у меня давно работает и ок - большая перегрузка биллинга из телекомуникац.учетной системы в 1С (доки в 1С создаются и проводятся) - ну как большая - около тысячи-полторы документов.. все проводится в одной большой транзакции, если где-то заткнулось - откатывается назад все - как написано выше
14 Злопчинский
 
21.10.11
16:31
(10) будет долбится. Потом истечет время ожидания (?) вывалится юзверю вопрос - попытаться еще раз если юзверь скаджет "нет" - то уйдет на следующую итерацию цикла?
15 vde69
 
21.10.11
16:43
(14)нет, выволится нафиг.
16 Злопчинский
 
21.10.11
18:26
(15) хреново...
.
итого вообщем обеспечить такую хотелку чтобы не прерывался цикл - получается что фиг вам...?
17 vde69
 
21.10.11
18:28
(16) можно через обработчик ожидания
18 Cthulhu
 
21.10.11
18:29
(13): блин... проведение - само по себе транзакция (см.мануал). вложенные транзакции 1с не поддерживает (см.мануал). поэтому не следует делать проведение в транзакции. на практике чревато искажением данных, иногда довольно причудливым и трудно локализируемым (например - наличием движений у непроведенного документа)...
Блин, вот от тебя подобного художества - точно не ожидал, коллега...
19 Cthulhu
 
21.10.11
18:30
(16): нет, не "фиг вам".
выведи проведение в отдельную обработку (в приоткрытии).
20 Cthulhu
 
21.10.11
18:31
(17): можно и так. с секундой. если проведение длиннее секунды - скорость будет та же, что при проведении "сплошняком".
21 МуМу
 
21.10.11
19:29
Таймаут SQL просто подбей на нужный.(в 1СПП можно метод нужный вызвать) Это делается просто.
22 Cthulhu
 
21.10.11
19:52
(21): ему "нужный" - такой, чтобы можно было сказать "пропустить" и 1с-код пошел выполняться дальше. такого там нет.
23 Злопчинский
 
21.10.11
22:08
(18) не знаю, лет сэм-восэм гружу данные и провожу их в транзакции и отменяю транзакцию при проблеме проведения (правда в монопольном режиме) - искажений данных замечено не было...
.
а какой еще способ например есть загнать 100 доков "в сеансе" - и если док не прошел - отменить весь сеанс..? собирать в списки а потом удалять если док не провелся..?
.
(19) про впроведение в контексте (0) - вообще речи не идет - это побочное обсуждение
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.