Имя: Пароль:
1C
1С v8
v8: Я ни чего не понял про управляемые блокировки, объясните
,
0 IvanovAl
 
01.06.13
16:59
На сайте 1с приведена статья об управляемых блокировках: http://v8.1c.ru/overview/Term_000000642.htm

В этой статье есть код, в котором меня смущает несколько моментов:
1. Зачем используется объект "Блокировка данных" если записи регистра блокируются в запросе?
2. Почему перед записью в регистр бухгалтерии не используется метод "Разблокировать"? Ведь тогда теряется смысл управляемости...
3. Зачем для регистра накопления вызывается метод "Записать"? Разве наличие наложенной блокировки отменяет запись движений по регистру?
1 Reaper_1c
 
01.06.13
17:56
(0) В статье ошибок нет. А вот в голове у тебя полный бардак. Учи вот матчасть: http://kb.1c.ru/articleView.jsp?id=30
2 IvanovAl
 
01.06.13
20:10
(1) В предложенной статье нет вопросов ни на один из трех вопросов. Только общие слова о том, что блокировки нужны, и как будет плохо без них...

Вы можете объяснить, зачем происходит двойное блокирование (запросом и объектом "БлокировкаДанных")? Почему блокировка не снимается после полностью завершенных чтения и записи? Зачем в самом конце модуля применен метод "Записать"?
3 eduspec82
 
01.06.13
20:21
(0) студентам рекомендуется блокировать данных как в типовых методом набора записей
посмотрите в типовой какой сможете разобраться
статьи рановато читать без навыка
4 IvanovAl
 
01.06.13
20:26
(3) Простите, но вопрос стоит по конкретному коду. Вы можете ответить на три вышеозначенных вопроса?
5 eduspec82
 
01.06.13
20:35
данные в запросе не блокируются при режиме управляемых блокировок никогда
режм записи по умолчанию наборов движений отличается в 8.1 и 8.2
разблокировать то зачем
учите матчасть (1) правильно сказал
7 IvanovAl
 
01.06.13
20:49
(5) Метод "Разблокировать" нужен, чтобы повысить параллельность работы пользователей, вынеся из времени блокирования безусловную запись в регистр бухгалтерии.
8 Reaper_1c
 
01.06.13
20:53
(6) Потому что ты даже не удосужился открыть документацию, где черным по белому написано, что конструкция "Для изменения" языка запросов не работает в транзакции, использующей управляемый режим. Иди учи матчасть.
9 eduspec82
 
01.06.13
21:00
(6) если вы ничего не поняли в 5 значит надо подучиться
в (7) это кто вам сказал гыгыгы
если кажется что вас оскорбляют значит карма плохая гыгыгы
10 EvgeniuXP
 
01.06.13
21:15
(3) а кто тебе сказал, что запрос блокирует данные??? 8-0 или в какой желтой книжке ты это прочитал???
11 IvanovAl
 
01.06.13
21:21
(8) А вот что написано в документации: http://s017.radikal.ru/i407/1306/1c/d1bc049d92a3.jpg

(9) Это в видеоуроках Гилеева и Насипова.

(10) Прочитал в документации. Если не блокирует, тогда зачем эта конструкция нужна?
12 eduspec82
 
01.06.13
21:23
имеется ввиду вероятно инструкция - "для изменения" которая при управляемых блокировках не действует
самое смешное в (7) производить запись сняв блокировку гыгыгы
13 hhhh
 
01.06.13
21:25
(11) мы же заблокировали регистр, чтобы записать в него. Зачем перед записью разблокировать? Кто ушлый сразу влезет, захватит регистр, и наша запись накроется медным тазом.
14 IvanovAl
 
01.06.13
21:28
(12) Другими словами вы подтверждаете, что в статье написано неверно.

Разумеется, строчку с записью в регистр накопления надо поднять до блока записи в регистр бухгалтерии и следом снять блокировку.
15 IvanovAl
 
01.06.13
21:29
У меня необходимость метода "Записать" для регистра накопления не вызывала вопросов. Сомнительным было место вызова этого метода (в конце процедуры проведения).
16 hhhh
 
01.06.13
21:32
(15) так и есть, все регистры автоматом записываются сразу после обработки проведения. Причем там куча подписок еще, то есть выполняется по факту может штук 10 обработок проведения, а это только первая. Так что не надо торопиться с записью.
17 IvanovAl
 
01.06.13
21:42
(16) Процедура "ОбработкаПроведения" приведена полностью. Никаких дополнительных обработок проведения в коде нет. Зачем выдумывать то чего нет?
18 Reaper_1c
 
01.06.13
21:46
Вот дятлы. Ну возьмите пустую конфигурацию, сделайте документ с таким модулем и убедитесь, что без этой строчки движения в регистр не попадают...
19 hhhh
 
01.06.13
21:48
(17) Есть подписки на событие ОбработкаПроведения. Есть Процедуры ПередЗаписью() ПриЗаписи() каждого регистра и подписки на эти процедуры. То есть там реально 200-300 процедур еще выполнится. Вы же увидели только одну. Может разблокировать есть, но в 75-й или в 88-й процедурке? С чего вы решили, что ее нет?
20 IvanovAl
 
01.06.13
22:05
(18) Успокойтесь, сегодня суббота. Без какой строчки данные в какой регистр не попадают?

(19) И вы считаете, что подобный код может быть примером программирования? Непонятно зачем отстаивается явно ошибочное решение поиском каких-то суперредких случаев (мне за 10 лет работы подобный код ни разу не встречался).
21 hhhh
 
01.06.13
22:13
это не я считаю. Фирма 1с так считает. Вот не считает она этот код ошибочным.
22 Reaper_1c
 
01.06.13
22:13
(20) Без принудительной записи.

Типовая БП, Типовая КА, Типовая УПП, 100500 доработанных конфигураций в стране стали суперредкостью? Вот это да....
23 Лефмихалыч
 
01.06.13
22:21
(0) Почитай "Профессиональную разработку", чтобы не задавать таких смешных вопросов. Там все эти темы раскрыты полностью до самых сисек.

1. в мануале написано, что, если у конфигурации или\и регистра установлен режим управления "Управляемый", то все "для изменения" игнорируются платформой с предельным цинизмом
2. Потому, что метод Разблокировать() вызывать не нужно - блокировка накладывается дл других сеансов и она не жействует на сеанс в котором инициирована. В этом смысл управляемость, не сочиняй ерунды.
3. Наложение блокировки не имеет ни какого отношения к записи регистра В принципе это вещи независимые. Набор записей при проведении записывается, если у него установлено свойство Записывать = Истина или вызван его метод Записать(), блокировки к этому ни какого отношения не имеют
24 IvanovAl
 
02.06.13
08:31
(22) И где в типовой БП в процедурах, выполняющихся в одной транзакции после "ОбработкаПроведения", производится запись в регистры и разблокировка наборов регистров? Конкретный пример, пожалуйста!

(23)
1. Значит я прав, и секция "ДЛЯ ИЗМЕНЕНИЯ" не нужна.
2. Метод "Разблокировать" надо вызывать сразу после записи в регистры, чтобы освободить общий ресурс (иначе надо ожидать окончания всей транзакции с кучей методов).
3. Значит я прав, и запись в регистр в конце процедуры проведения не имеет смысл.
25 Лефмихалыч
 
02.06.13
08:33
(24) ты таки ни фига не понял. Блокировку не надо снимать. Надо код организовывать так, чтобы в обработке проведения не было ни чего после записи регистров.

Имеет или нет - это решать тому, кто пишет код. Бывает, что и имеет.
26 GROOVY
 
02.06.13
09:20
Мда...
27 IvanovAl
 
02.06.13
11:12
(25) Повторю: в представленном на сайте 1с коде блокировка регистра накопления излишне увеличена по времени из-за безусловной записи в регистр бухгалтерии. Надо перенести запись в регистр накопления и последущее снятие блокировки до записи в регистр бухгалтерии.

К тому же в транзакции записи документа будет вызвано еще много обработчиков (смотри (19)). Затягивать блокировку регистра- глупость.

Мы рассматриваем, не кусок конфигурации, а ПРИМЕР работы с управляемыми блокировками (по крайне мере так этот код преподносит 1с). Так что не надо выдумывать смыслы, которых нет.
28 ptiz
 
02.06.13
12:05
(27)
А разве есть метод "Разблокировать" у блокировки?
И без "разблокировать" смысл управляемости не теряется, т.к. смысл в том, чтобы блокировать не весь регистр, а только по нужным измерениям.
Блокировка снимается только по окончании транзакции.
Если чисто теоретически допустить возможность разблокировки до окончания "общей" транзакции, то будут такие ситуации:
1) записали данные в регистр, сняли блокировку
2) второй документ получил новые данные
3) по какой-то причине 1ая "общая" транзакция до конца не завершилась, надо откатить её и удалить сделанные движения по разблокированному регистру, и тут возможны варианты:
а) второй документ уже провелся, исходя из неверных данных - получили косяк в учете
б) второй документ еще проводится и данные заблокированы им... тут вообще непонятно что
30 IvanovAl
 
02.06.13
13:13
А вот как Радченко советует в своей книге "Коротко о главном":

Модуль документа "Расход товара", конфигурация "Управляемое приложение":
Процедура ОбработкаПроведения(Отказ, Режим)

   // Формирование движений регистров накопления ТоварныеЗапасы и Продажи.
   Движения.ТоварныеЗапасы.Записывать = Истина;
   Движения.Продажи.Записывать = Истина;
   Если Режим = РежимПроведенияДокумента.Оперативный Тогда
       Движения.ТоварныеЗапасы.БлокироватьДляИзменения = Истина;
   КонецЕсли;    

   // Создадим запрос, чтобы получать информацию об услугах
   Запрос = Новый Запрос("ВЫБРАТЬ
                         |    ТоварыВДокументе.НомерСтроки КАК НомерСтроки
                         |ИЗ
                         |    Документ.РасходТовара.Товары КАК ТоварыВДокументе
                         |ГДЕ
                         |    ТоварыВДокументе.Ссылка = &Ссылка
                         |    И ТоварыВДокументе.Товар.Вид = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)");

   Запрос.УстановитьПараметр("Ссылка", Ссылка);
   РезультатУслуги = Запрос.Выполнить().Выгрузить();
   РезультатУслуги.Индексы.Добавить("НомерСтроки");

   Для каждого ТекСтрокаТовары Из Товары Цикл

       Строка = РезультатУслуги.Найти(ТекСтрокаТовары.НомерСтроки, "НомерСтроки");
       Если Строка = Неопределено Тогда
           
           // Не услуга
           Движение = Движения.ТоварныеЗапасы.Добавить();
           Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
           Движение.Период = Дата;
           Движение.Товар = ТекСтрокаТовары.Товар;
           Движение.Склад = Склад;
           Движение.Количество = ТекСтрокаТовары.Количество;

       КонецЕсли;

       Движение = Движения.Продажи.Добавить();
       Движение.Период = Дата;
       Движение.Товар = ТекСтрокаТовары.Товар;
       Движение.Покупатель = Покупатель;
       Движение.Количество = ТекСтрокаТовары.Количество;
       Движение.Сумма = ТекСтрокаТовары.Сумма;

   КонецЦикла;

   // Формирование движения регистра накопления Взаиморасчеты.
   Движения.Взаиморасчеты.Записывать = Истина;
   Движение = Движения.Взаиморасчеты.Добавить();
   Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
   Движение.Период = Дата;
   Движение.Контрагент = Покупатель;
   Движение.Валюта = Валюта;

   Если Валюта.Пустая() Тогда
       Движение.Сумма = Товары.Итог("Сумма");
   Иначе

       Курс = РегистрыСведений.КурсыВалют.ПолучитьПоследнее(Дата, Новый Структура("Валюта", Валюта)).Курс;

       Если Курс = 0 Тогда
           Движение.Сумма = Товары.Итог("Сумма");
       Иначе
           Движение.Сумма = Товары.Итог("Сумма") / Курс;
       КонецЕсли;

   КонецЕсли;

   //Запишем движения
   Движения.Записать();
   
   //Контроль остатков при оперативном проведении
   Если Режим = РежимПроведенияДокумента.Оперативный Тогда
       // Создадим запрос, чтобы контролировать остатки по товарам
       Запрос = Новый Запрос("ВЫБРАТЬ
                             |    ТоварыВДокументе.Товар КАК Товар,
                             |    СУММА(ТоварыВДокументе.Количество) КАК Количество,
                             |    МАКСИМУМ(ТоварыВДокументе.НомерСтроки) КАК НомерСтроки
                             |
                             |ПОМЕСТИТЬ ТребуетсяТовара
                             |
                             |ИЗ
                             |    Документ.РасходТовара.Товары КАК ТоварыВДокументе
                             |
                             |ГДЕ
                             |    ТоварыВДокументе.Ссылка = &Ссылка
                             |    И ТоварыВДокументе.Товар.Вид = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Товар)
                             |
                             |СГРУППИРОВАТЬ ПО
                             |    ТоварыВДокументе.Товар
                             |
                             |ИНДЕКСИРОВАТЬ ПО
                             |    Товар
                             |;
                             |
                             |////////////////////////////////////////////////////////////////////////////////
                             |ВЫБРАТЬ
                             |    ПРЕДСТАВЛЕНИЕ(ТребуетсяТовара.Товар) КАК ТоварПредставление,
                             |    ВЫБОР
                             |        КОГДА - ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0) > ТоварыВДокументе.Количество
                             |            ТОГДА ТоварыВДокументе.Количество
                             |        ИНАЧЕ - ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0)
                             |    КОНЕЦ КАК Нехватка,
                             |    ТоварыВДокументе.Количество - ВЫБОР
                             |        КОГДА - ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0) > ТоварыВДокументе.Количество
                             |            ТОГДА ТоварыВДокументе.Количество
                             |        ИНАЧЕ - ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0)
                             |    КОНЕЦ КАК МаксимальноеКоличество,
                             |    ТребуетсяТовара.НомерСтроки КАК НомерСтроки
                             |
                             |ИЗ
                             |    ТребуетсяТовара КАК ТребуетсяТовара
                             |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварныеЗапасы.Остатки(
                             |                ,
                             |                Товар В
                             |                        (ВЫБРАТЬ
                             |                            ТребуетсяТовара.Товар
                             |                        ИЗ
                             |                            ТребуетсяТовара)
                             |                    И Склад = &Склад) КАК ТоварныеЗапасыОстатки
                             |        ПО ТребуетсяТовара.Товар = ТоварныеЗапасыОстатки.Товар
                             |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.РасходТовара.Товары КАК ТоварыВДокументе
                             |        ПО ТребуетсяТовара.Товар = ТоварыВДокументе.Товар
                             |            И ТребуетсяТовара.НомерСтроки = ТоварыВДокументе.НомерСтроки
                             |
                             |ГДЕ
                             |    ТоварыВДокументе.Ссылка = &Ссылка И
                             |    0 > ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0)
                             |
                             |УПОРЯДОЧИТЬ ПО
                             |    НомерСтроки");

       Запрос.УстановитьПараметр("Склад", Склад);
       Запрос.УстановитьПараметр("Ссылка", Ссылка);
       РезультатСНехваткой = Запрос.Выполнить();

       ВыборкаРезультатаСНехваткой = РезультатСНехваткой.Выбрать();

       // Выдадим ошибки для строк, в которых не хватает остатка
       Пока ВыборкаРезультатаСНехваткой.Следующий() Цикл

           Сообщение = Новый СообщениеПользователю();
           Сообщение.Текст = НСтр("ru = 'Не хватает '", "ru")
               + ВыборкаРезультатаСНехваткой.Нехватка
               + НСтр("ru = ' единиц товара'", "ru") + """"
               + ВыборкаРезультатаСНехваткой.ТоварПредставление
               + """"
               + НСтр("ru = ' на складе'", "ru")
               + """"
               + Склад
               + """."
               + НСтр("ru = 'Максимальное количество: '", "ru")
               + ВыборкаРезультатаСНехваткой.МаксимальноеКоличество
               + ".";
           Сообщение.Поле = НСтр("ru = 'Товары'", "ru")
               + "["
               + (ВыборкаРезультатаСНехваткой.НомерСтроки - 1)
               + "]."
               + НСтр("ru = 'Количество'", "ru");
           Сообщение.УстановитьДанные(ЭтотОбъект);
           Сообщение.Сообщить();
           Отказ = Истина;

       КонецЦикла;

   КонецЕсли;
   
КонецПроцедуры


Видно, что ничего общего с примером 1с этот код не имеет и с моей стороны вызывает только одно нарекание: запись в регистры общая (а значит в последовательности дерева метаданных, что может задержать блокировку). Зато понижаются DeadLock-и (так как разные документы пишут регистры в одинаковой последовательности)
31 eduspec82
 
02.06.13
13:40
могу себе представить как такой "гуру" с десятилетним опытом (хм :)) запарил коллег с вопросами почему да почему да еще с наездами
а ответ один - учите матчасть :)
32 krbIso
 
02.06.13
13:51
понижаются дедлоки это круто)

вообще не понятно в чем претензия то
33 IvanovAl
 
02.06.13
15:20
(31) интересно, где у меня наезды и фразы "учите мат.часть"?

(32) к словам придираемся? Признак того, что спор слит...
Сформулирую так: количество дедлоков уменьшается.