Имя: Пароль:
1C
1С v8
Пакетное создание документов. Блокировка данных
0 Wefast
 
01.07.19
13:22
Обработка создает документы. Нужно чтобы все эти документы находились рядом.

Я так понимаю на время работы обработки мне нужно заблокировать возможность создания документов пользователем.

Как это правильно делается?

Просто перед началом цикла где создаются документы написать

    Блокировка = Новый БлокировкаДанных;
    ЭлементБлокировки = Блокировка.Добавить("Документы.МойДок");
    ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
    Блокировка.Заблокировать();

Я не очень понимаю в какой момент документы разблокируются. И я так понимаю пользователи даже не смогут открыть документы в это время.

Или достаточно все это сделать в транзакции. И момент когда выполнить ЗАфиксироватьТранзакцию() все документы последовательно запишутся и получать нужные номера. И в этот момент другой пользователь ничего записать не сможет.

Или документы на самом деле создадутся по мере работы обработки. А по окончании транзакции либо удалятся если была ошибка, либо останутся на месте и станут видны?

Или нужно как то совместить транзакцию и блокировку?
1 H A D G E H O G s
 
01.07.19
13:24
Ты все правильно сказал
2 H A D G E H O G s
 
01.07.19
13:25
НачатьТранзакцию()
//Тут другой пользователь еще может создать док

Блокировка.Заблокировать();
// Тут другой пользователь уже не может

ЗафиксироватьТранзакцию();
// Тут другой пользователь уже может
3 H A D G E H O G s
 
01.07.19
13:28
Для текущей транзакции и текущего пользователя
Документы записываются сразу же в момент
ДокОбъект.Записать()
и получают номера
Однако, если будет ошибка и выполнение не дойдет до ЗафиксироватьТранзакцию() - то все откатится до начального состояния
Для всех других пользователей доки создадутся мгновенно, после ЗафиксироватьТранзакцию()
4 Wefast
 
01.07.19
13:35
(3) тогда все делать в транзакции не обязательно?(только если мне нужно проследить чтобы все документы в принципе создались) Последовательность сохранится только если я напишу Заблокировать(), правильно?
5 Cyberhawk
 
01.07.19
13:36
(4) Блокировка вне транзакции в упр. режиме вызывает исключение, а в авт. просто не работает
6 Wefast
 
01.07.19
13:43
Значит как итог это будет так?

Процедура СозданиеДок()


  НачатьТранзакцию();
    Блокировка = Новый БлокировкаДанных;
    ЭлементБлокировки = Блокировка.Добавить("Документы.МойДок");
    ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
    Блокировка.Заблокировать();

    Для Стр из ТЧ Цикл
      Док = Документы.МойДок.СоздатьДокумент();
      Док.Записать()
    КонецЦикла;
  Попытка
    ЗафиксироватьТранзакцию();
  Исключение
    ОтменитьТранзакцию();
  КонецПопытки;
КонецПроцедуры
7 Cyberhawk
 
01.07.19
13:47
Цикл неправильно организован. Запись документа в попытке и в исключении взвод флага отказа. Вне цикла - анализ флага и фиксация / отмена транзакции.
8 Wefast
 
01.07.19
13:52
(7)

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

Но спасибо, наверное так правильно с точки зрения хорошего тона писать, надо мне это или нет.
9 Cyberhawk
 
01.07.19
14:04
(8) "если запись документа сделать через попытку, то транзакция не выпадет с ошибкой и можно будет записать то что может записаться" // Увы, в одной транзакции такого не добиться - нужно как минимум две (в первой записываем всех и собираем удачных кандидатов и откатываем транзакцию, во второй уже записываем только удачных)
10 Wefast
 
01.07.19
14:09
(9) тогда зачем запись делать через попытку? Не понимаю, если все равно при попытке записи попадет в исключение с отменой транзакции, зачем делать запись через попытку.
11 Cyberhawk
 
01.07.19
14:14
(10) Чтобы собрать перечень ошибок сразу по всей выборке, а не свалиться в исключение на первой же ошибке
12 Cyberhawk
 
01.07.19
14:14
Конечно же оба подхода имеют право на существование - все зависит от ситуации и потребности