![]() |
![]() |
![]() |
|
Подскажите как создать подписки для управляемых блокировок | ☑ | ||
---|---|---|---|---|
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) А зачем? Это вообще бессмысленно. Может тебе сначала стоит понять что такое транзакционная блокировка и Уровень изоляции транзакции?
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |