Имя: Пароль:
1C
 
Подскажите как создать подписки для управляемых блокировок
0 Alex_MA
 
19.05.11
09:19
Всем доброго дня!

Есть процедура блокировки документа "РеализацияТоваровУслуг", а так же всех связных по нему регистров и последовательностей.

Вот ее код (Может кому пригодится):


РежимБлокировки = РежимБлокировкиДанных.Исключительный;
   
   Блокировка = Новый БлокировкаДанных();
   
   ИмяОбъектаПространстваБлокировокДокумент = "Документ." + Источник.Метаданные().Имя;
   
   //Блокировка самого документа
   ЭлементБлокировки = Блокировка.Добавить(ИмяОбъектаПространстваБлокировокДокумент);
   ЭлементБлокировки.Режим = РежимБлокировки;
   ЭлементБлокировки.УстановитьЗначение("Ссылка", Источник.Ссылка);
   
   //Определения имени пространства для "Последовательность"
   Для Каждого ТекПоследовательность Из Последовательности Цикл
       Если ТекПоследовательность.Принадлежит(Источник.Ссылка) Тогда
           //Необходимо заблокировать последовательность    
           ЭлементБлокировки = Блокировка.Добавить("Последовательность." + Прав(Строка(ТекПоследовательность), СтрДлина(Строка(ТекПоследовательность)) - Найти(Строка(ТекПоследовательность), ".")) + ".НаборЗаписей");
           ЭлементБлокировки.Режим = РежимБлокировки;
           ЭлементБлокировки.УстановитьЗначение("Регистратор", Источник.Ссылка);
       КонецЕсли;    
   КонецЦикла;
   
   //Определения имени пространства для "Регистров"
   КоллекцияДвижений = Источник.Метаданные().Движения;
   Для Каждого ТекРегистрДвижения Из КоллекцияДвижений Цикл
       
       ПодчиненностьРегистратору = Ложь;
       ИмяРегистра = ТекРегистрДвижения.Имя;
       ТипРегистра = "";
       
       Если Метаданные.РегистрыНакопления.Найти(ИмяРегистра) <> Неопределено Тогда
           ТипРегистра = "РегистрНакопления";
           ПодчиненностьРегистратору = Истина;
       ИначеЕсли Метаданные.РегистрыСведений.Найти(ИмяРегистра) <> Неопределено Тогда
           ТипРегистра = "РегистрСведений";
           Если Метаданные.РегистрыСведений.Найти(ИмяРегистра).РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
               ПодчиненностьРегистратору = Истина;
           КонецЕсли;
       ИначеЕсли Метаданные.РегистрыБухгалтерии.Найти(ИмяРегистра) <> Неопределено Тогда
           ТипРегистра = "РегистрБухгалтерии";
           ПодчиненностьРегистратору = Истина;
       КонецЕсли;    
       
       Если ТипРегистра <> "" Тогда
           Если ПодчиненностьРегистратору Тогда
               ЭлементБлокировки = Блокировка.Добавить(ТипРегистра + "." + ИмяРегистра + ".НаборЗаписей");
               ЭлементБлокировки.Режим = РежимБлокировки;
               ЭлементБлокировки.УстановитьЗначение("Регистратор", Источник.Ссылка);
               
           Иначе    
               //Блокировка некоторых регистров сведений по измерениям,
               //которые не подчинены регистратору
               //..
           КонецЕсли;
       КонецЕсли;    
       
   КонецЦикла;
   
   //Установка блокировки
   Попытка
       Блокировка.Заблокировать();
   Исключение
       ОбщегоНазначения.СообщитьОбОшибке(ОписаниеОшибки(), Отказ, "Не удалось заблокировать объекты");
       ВызватьИсключение "Операция не выполнена";
   КонецПопытки;

Как создать подписки на события для активации подписки ??? Сколько их надо (подписок)?

Вопрос созрел потому, что я не знаю как происходят транзакции при проведении или записи.

Т.е. если мы создадим подписку на событие "ПередЗаписью" и вставим в обработчик вышеописанный код, то программа при записи или проведении документа сначала выполняет код в модуле объекта, а потом уже в подписке.

Т.е. нажимаем кнопку "Провести" -> ПередЗаписью (МодульОбъекта) -> ПодпискаПередЗаписью (Если она есть) -> ОбработкаПроведения (МО) -> ПодпискаОбработкаПроведения (Если она есть)

Т.е. получается, что перед модификацией объекта мы никак не можем установить блокировку.
ИМХО мой вывод - надо прописывать вызов процедуры блокировки прямо из процедуры таким образом (Наверно я не прав здесь, но мне так кажется)

Процедура ОбработкаПроведения(Отказ)
    УправлениеБлокировками.УстановитьУпрБлокировку(Ссылка);

    //Тело процедуры проведения
КонецПроцедуры

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

Спасибо за внимание.Надеюсь дочитали вопрос.
1 Alex_MA
 
19.05.11
09:41
подниму ?
2 Dem1urg
 
19.05.11
09:52
(0) Выводы правильные.
Управляемые блокировки имеют смысл ТОЛЬКО в ОбработкаПроведения. ОбработкаПроведения ВСЕГДА выполняется в транзакции.
3 Alex_MA
 
19.05.11
10:04
(2)Т.е. подписка на событие "ОбработкаПроведения", где располагается код блокировки  нам не подходит, т.к выполнение при нажатии на кнопку провести:

ОбработкаПроведения (МО) -> ПодпискаНаСобытие"ОбработкаПроведения"(Блокировка)

а нам надо

Блокировка->ОбработкаПроведения(МО)

Т.е. надо в каждой процедуре ОбработкаПроведения МО писать что то вроде:


Процедура ОбработкаПроведения(Отказ)
    УправлениеБлокировками.УстановитьУпрБлокировку(Ссылка);

    //Тело процедуры проведения

КонецПроцедуры

Получается так ?
4 Dem1urg
 
19.05.11
10:25
Да. А что здесь не так? Предполагается что для каждого вида документа должен быть свой алгоритм установки блокировок определяемый его бизнес-логикой.
5 Alex_MA
 
19.05.11
10:30
(4)А если один вид документа, то подписка ведь тоже не подходит. Так ?
6 Alex_MA
 
19.05.11
10:53
Код в (0) блокирует вот по такому принципу.
http://www.imagepost.ru/images/e/cm/ecmkncfdfmagneglbqglbfkxiqqpoy.png
Вопрос, будет ли блокировка документа №2 при чтении остатков из регистра ???
7 Alex_MA
 
19.05.11
10:54
8 Alex_MA
 
19.05.11
10:55
9 Alex_MA
 
19.05.11
11:52
up ?
10 Alex_MA
 
19.05.11
15:13
точнее ИсключительнаяБлокировка - писсимистическая ?
11 Dem1urg
 
19.05.11
15:15
(10) Ты путаешь теплое с мягким. Оптимистическая и пессемистическая это ОБЪЕКТНЫЕ блокировки. Они влияют только на пользовательский интерфейс. Заблокированные таким образом объекты можно изменять программно. А вот ТРАНЗАКЦИОННЫЕ блокировки могут быть исключительными и разделяемыми. Разделяемая разрешает чтение из других транзакций, но запрещает изменение, а исключительная запрещает вообще всё.
12 Alex_MA
 
19.05.11
15:18
(11)Вот теперь все понятно. Спасибо большое.
13 Alex_MA
 
19.05.11
15:21
однако при разделяемой есть вероятность ошибки, например при проведении 2 документов реализаций в которых списывается по 5 яблок программа даст списать 10 (потому что в один момент каждая из них получила остаток в 5 яблок), при реальном присутствии их на складе в 5 яблок.
14 Alex_MA
 
19.05.11
15:43
Из (13) видно, что разделяемая блокировка при чтении - зло, понятно!
А разделяемая блокировка при записи чем чревата ?
15 Alex_MA
 
19.05.11
15:45
(14)Проблема потерянного изменения ?
16 Dem1urg
 
19.05.11
17:08
(13)-(15) Ты недопонял. Данные, которые ты хочешь ИЗМЕНИТЬ при проведении блокируются исключительной блокировкой. Данные, НЕИЗМЕННОСТЬ которых ты хочешь гарантировать в процессе проведения блокируются разделяемой.
Простейший пример остатки и резервы. При проведении тебе нужно проверить достаточность остатков с учетом резервов, но движения будут сделаны только по регистру остатков. Чтобы быть уверенным, что ты не превысишь резерв на него накладывается разделяемая блокировка. Т.е. посмотреть резерв другие могут, а вот поменять уже нет.
17 Dem1urg
 
19.05.11
17:10
(15) Нет. Изменения потеряны не будут. Возможны нарушения только бизнес-логики. Например появление отрицательных остатков на складе.
18 Alex_MA
 
20.05.11
08:24
(16)Думаю последний вопрос.
Если есть документ, он не проведен и накладывается блокировка такого вида:

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

ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.РасчетыСКонтрагентами.НаборЗаписей");
ЭлементБлокировки.Режим = РежимБлокировки;
ЭлементБлокировки.УстановитьЗначение("Регистратор", Источник.Ссылка);

//Устанавливается блокировка на регистр по проводимому документу. Как заблокируется, если данный документ еще не проведен ???
19 Dem1urg
 
20.05.11
09:29
(18) Блокировка накладывается только на время выполнения операции проведения. Все управляемые блокирвоки снимаются автоматически после завершения процедуры ОбработкаПроведения.
20 Alex_MA
 
20.05.11
10:39
(19)Это я понимаю.
Вопрос вот в чем:

Процедура ОбработкаПроведения(Отказ)

    //Документ не проведен
    УправлениеБлокировками.УстановитьУпрБлокировку(Ссылка);

    //Тело процедуры проведения


КонецПроцедуры

А в процедуре блокировки код из (18)
21 Dem1urg
 
20.05.11
15:32
(20) Ну и? В чем вопрос то?
22 NcSteel
 
20.05.11
15:34
(0) Переходи на 8.2 , там все реализовано.
23 Dem1urg
 
21.05.11
17:08
(22) Режим управляемых блокировок в 8.2 практически не изменился по сравнению с 8.1
24 Alex_MA
 
21.05.11
19:33
(21)Как наложиться блокировка на РН по пространству блокировок "Регистратор", если записей по этому регистру с этим регистратором еще нет
25 Dem1urg
 
21.05.11
21:13
(24) А зачем? Это вообще бессмысленно. Может тебе сначала стоит понять что такое транзакционная блокировка и Уровень изоляции транзакции?
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший