gifts2017

Что на самом деле делает свойство «БлокироватьДляИзменения»

Опубликовал Андрей Бурмистров (Andreynikus) в раздел Программирование - Практика программирования

Мотивацией к написанию данной статьи, послужило большое количество заблуждений касаемо свойства «БлокироватьДляИзменения».
Большая часть материалов в сети, посвящена либо управляемым блокировкам, либо режиму разделения итогов, свойство «БлокироватьДляИзменения» затрагивается лишь частично без конкретики, в итоге у многих возникают вопросы при его использовании.
Цель данной статьи заполнить этот пробел.
Прошу сначала прочитать статью полностью и только после этого делать выводы.
Надеюсь, данный материал будет кому-то полезен.

Что бы понять материал данной статьи, нужно хорошо знать и понимать 2 вещи:

1. Что такое режим разделения итогов. Если вы вдруг не в курсе, то рекомендую обратиться к данной статье на ИТС. Там все очень подробно и понятно написано. 

2. Новая методика контроля остатков (остатки контролируются после записи)


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

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

Но как быть, если например у регистра есть 2 регистратора, и один документ использует контроль остатков, а второй нет?

В этом случае нам как раз и пригодится свойство набора записей регистров накопления и бухгалтерии «БлокироватьДляИзменения».

 

Начнем с того, что использовать «БлокироватьДляИзменения» имеет смысл, только если выполняются все следующие условия:

- транзакция выполняется в управляемом режиме (если использовать в автоматическом, то возникнет ошибка)

- у регистра включен режим разделения итогов (если он выключен, то свойство не имеет смысла и будет просто игнорироваться)

- используется новая методика контроля остатков (остатки контролируются после записи)

(в старой методике не имеет смысла, т.к. там нужно накладывать блокировку до записи в регистр)

 

Если хотя бы одно из этих условий не выполняется, то нет смысла использовать «БлокироватьДляИзменения».

Поэтому все сказанное ниже применимо только если выполняются все 3 условия.

 

А что это свойство делает?

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

 А поподробнее?

Тут необходимо расписать каждую фразу, что бы исключить неправильную трактовку. 

«… оно отключает разделитель итогов»

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

Повторю еще раз, свойство фактически ничего не блокирует, блокирует платформа без вашего участия, свойство лишь на время отключает разделитель итогов по данному набору измерений.

 

А зачем вообще отключать разделитель итогов?

Если не отключить разделитель итогов, то платформа накладывает управляемую блокирвоку по ключу Склад+Товар+Разделитель.

В результате возможны следующие последствия:

При использовании СУБД блокировочника - возможна взаимоблокировка.
При использовании версионника - возможно списание остатков в минус.

 

Давайте разберем эти случаи подробнее.

Если используется блокировочник.

В случае с блокировочником, дедлок получается довольно просто, две транзакции параллельно записывают свои данные по одному набору измерений, платформа это позволяет т.к. используется разделитель итогов. После этого обе транзакции хотят проверить остатки, а для этого нужны все строки по ключу Склад+Товар (т.е. без учета разделителя). В итоге ни одна из транзакций не может прочитать все строки, т.к. часть строк захвачена другой транзакцией (разделитль "мешает" захватить все строки).

Схема этой взаимоблокировки представлена в таблице.

Пример взаимоблокировки

В этом случае, по своему назначению, «БлокироватьДляИзменения» это аналог параметра «ДЛЯ ИЗМЕНЕНИЯ» в запросе чтения остатков в автоматическом режиме, только работает иначе.

Если включить «БлокироватьДляИзменения», то мы отключим разделитель итогов, и при записи сразу будет наложена управляемая блокировка Склад+Товар, и транзакция 2 не сможет добавить вторую строку, т.к. данный набор измерений будет уже заблокирован.

При использовании «БлокироватьДляИзменения», блокировка является следствием отключения разделителя итогов для предотвращения  дедлока. Можно сказать, что это своего рода полезный побочный эффект.

Но даже если бы мы не использовали БлокироватьДляИзменения (и рискнули нарваться на дедлок), то остатки в минус все равно бы не списались, т.к. все нужные строки по ключу Склад+Товар (без учета разделителя) были бы заблокированы запросом остатков.

Много путаницы возникает из-за названия этого свойства, поэтому сразу непонятно как оно работает. В данном случае название не соответствует тому, что свойство делает на самом деле (оно ничего не блокирует, оно отключает разделитель), но название соответствует получаемому результату (в итоге получаем блокировку по всем нужным записям). 


Если используется версионник

В этом случае, заблокированные строки первой транзакции, никак не помешают 2-й транзакции прочитать остатки (т.к. в версионнике пишущие не блокируют читающих).

Вторая транзакция спокойно прочитает старую версию данных (версию на момент начала первой транзакции) и спишет остаток в минус.

Что бы этого не допустить нужна управляемая блокировка на уровне 1С.

Если поставить БлокироватьДляИзменения = Истина, мы как раз получим такую блокировку, и данные будут заблокированы на уровне платформы.

 

«по записываемому набору измерений»

Разделитель отключается только для данного набора измерений.

Это значит, что режим разделения итогов на регистр в целом сохраняется и если у других наборов измерений БлокироватьДляИзменения =  Ложь, то они могут быть записаны параллельно.

 

Пример:

Допустим что одновременно встретились 6 транзакций и попытались одновременно записать данные в регистр, при этом разделитель итогов естественно включен.

Первые 2 транзакции делают расход и контролируют остатки, другие 4 делают приход и контроль остатков им не нужен.

Тогда мы получим такую картину.

Пример использования БлокироватьДляИзменения

Транзакция 1 оказалась на долю секунды быстрее всех и в момент записи данных установила исключительную управляемую блокировку без учета разделителя итогов (т.к. БлокироватьДляИзменения = Истина)

Транзакции 2 и 6 ждут Транзакцию 1, т.к. набор измерений у них одинаковый.

В данном случае без разницы какое значение «БлокироватьДляИзменения» установлено для транзакций 2 и 6, важно что набор измерений одинаковый, и он уже заблокирован, так что они не смогут параллельно записать свои данные. 

Транзакции 3 и 4 успешно записали свои данные параллельно, т.к. включен разделитель (БлокироватьДляИзменения = Ложь).

Транзакция 5 успешно записала данные параллельно, т.к. используется отличный от транзакции 1 набор измерений. 

 

«начиная с момента записи до конца транзакции»

Разделитель итогов отключается только в тот момент, когда начинается запись данных регистра и действует до тех пор, пока не закончится транзакция проведения документа.

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

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

Таким образом, если произойдет откат транзакции, свойство автоматически примет значение «Ложь» 

 

А что будет, если установить БлокироватьДляИзменения = Истина для регистра, у которого выключен режим разделения итогов? 

Ровным счетом ничего, не будет даже ошибки, просто данная строка кода будет проигнорирована.


А как же явные управляемые блокировки, они теперь не нужны?

Да, это еще один плюс данного свойства. При его использовании не нужно писать явные управляемые блокировки, достаточно одной строки Движения.НужныйРегистр.БлокироватьДляИзменения = Истина, это делает код компактнее и читабельнее.

 

А можно пример?

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

В таком случае код модуля проведения будет выглядеть следующим образом:

 

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

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

 

Строку «Движения.ОстаткиТоваров.БлокироватьДляИзменения = Истина;» можно писать в любом месте процедуры, для удобства лучше это делать в конце.

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

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


Выводы:

1. Данное свойство нужно использовать, только если соблюдаются все 3 условия:

- транзакция выполняется в управляемом режиме

- у регистра включен режим разделения итогов

- используется новая методика контроля остатов (остатки контролируются после записи) 

2. Несмотря на название, свойство ничего не блокирует, оно отключает режим разделения итогов, следствием этого является блокировка всех нужных записей (без учета разделителя). 

3. При использовании «БлокироватьДляИзменения», явные управляемые блокировки ставить не нужно.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Ivan Khorkov (vano-ekt) 05.08.13 08:22
>>Что на самом деле делает свойство «БлокироватьДляИзменения»

Лучше так:
Вся правда о свойстве «БлокироватьДляИзменения»!
2. ффф ыыы (zqzq) 05.08.13 09:59
РегистрНакопленияНаборЗаписей.<Имя регистра накопления>.БлокироватьДляИзменения

БлокироватьДляИзменения (LockForUpdate)

Использование:
Чтение и запись.

Описание:
Тип: Булево.
Устанавливает режим, при котором в процессе записи набора будет установлена управляемая блокировка для всех комбинаций измерений в соответствии с записями набора записей. Имеет смысл использовать, если проверка итогов регистра выполняется после записи и заблокировать нужно именно те комбинации, по которым записываются записи. В этом случае можно не использовать объект БлокировкаДанных.
При попытке использования в автоматическом режиме блокировки вызывает исключительную ситуацию. После успешной записи документа свойство устанавливается в Ложь у всех наборов записей.
При отмене транзакции значение свойства восстанавливается в состояние до транзакции.
Значение по умолчанию Ложь.

Доступность:
Сервер, толстый клиент, внешнее соединение.
Т. е. по сути тот же эффект, что и вручную создать объект БлокировкаДанных и описать область блокировки. Но ПространствоБлокировки может включать в себя и Справочник.<имя>, Документ.<имя>, ПланОбмена.<имя>, ПланСчетов.<имя>.

Т. е. возникает сомнение, при чём тут вообще разделение итогов? Т. к. блокировка накладывается на основную таблицу регистра, а не на таблицу итогов (или я чего-то не понимаю).

Установили исключительную блокировку на комбинацию измерений регистра перед записью => другая транзакция тоже пытается установить исключительную блокировку и не удаётся => ждёт пока первая транзакция не закончится и блокировка не снимется => устанавливает блокировку и записывает. Т. е. по идее блокировка происходит ДО записи, а разделение итогов нужно для параллельной записи в таблицу итогов по набору измерений (т. е. это вообще другая история).

upd: Установка свойства разделение итогов приводит к реструктуризации таблиц ИБ - в таблицу итогов добавляется колонка "Splitter" как виртуальное измерение. Отключение свойства приводит к обратному эффекту (и ещё дублирующие записи должны сливаться с суммированием). Т. е. это довольно затратная операция. Можно проверить вызвав в отладчике функцию ПолучитьСтруктуруХраненияБазыДанных().
3. Трактор Трактор (Трактор) 05.08.13 12:03
4. Андрей Бурмистров (Andreynikus) 05.08.13 14:29
(2) zqzq,
Не очень понятно, что вы хотите сказать.
Тем не менее, попробую ответить.

"Т. е. по сути тот же эффект, что и вручную создать объект БлокировкаДанных и описать область блокировки".

Если остатки контролируются после записи, то упр. блокировка будет поставлена автоматически, зачем ставить явную управляемую блокировку еще раз?

В самом начале статьи, русским по белому написано, что данное свойство используется, только если необходимо проверять остатки после записи (используется новая методика).
И если я вас правильно понял, вы спрашиваете, зачем использовать новую методику (контроль остатков после записи), если можно использовать старую совместно с явными управляемыми блокировками.

Объяснить вам преимущества контроля остатков после записи не цель данной статьи, подразумевается, что читатель это уже знает. Об этом так же было написано в начале.


"Т. е. возникает сомнение, при чём тут вообще разделение итогов? Т. к. блокировка накладывается на основную таблицу регистра, а не на таблицу итогов (или я чего-то не понимаю)"

Накладывается управляемая блокировка, а она работает с объектами 1С (а не таблицами СУБД), и если вы накладываете управляемую блокировку на пространство набор записей регистра, то уже не важно что будет заблокировано на уровне СУБД, т.к. встроенной менеджер блокировок 1С запретит изменять указанные записи регистра.

"Установка свойства разделение итогов приводит к реструктуризации таблиц ИБ - в таблицу итогов добавляется колонка "Splitter" как виртуальное измерение"

Спасибо, Кэп :)
Думаю это и так всем понятно, тем более что приведена ссылка на статью ИТС

Если я вас не так понял, то прошу поконкретнее формулировать свои вопросы.
5. Андрей Бурмистров (Andreynikus) 05.08.13 14:30
(3) Трактор,
Странно, проверял перед публикацией, видимо после модерации слетела
Спасибо что написали, исправлю
6. ZLENKO.PRO (ZLENKO) 05.08.13 16:13
Статья хорошая - автору "зачет"!
7. Роман Озеряный (rozer) 05.08.13 22:38
конечно неплохо перед
// Далее код проверки остатков …

вставить движения.записать() а так статья оч. полезная для тех у кого нет доступа к "партнерке" 1с :)
8. Р С (Dach) 06.08.13 00:29
Очень доходчиво все изложено, спасибо автору. Вопрос - а фактически, когда транзакция будет завершена? То есть когда "заблокированный" набор записей станет доступным и начнут свои действия другие транзакции?
9. Игорь Хитров (Новенький_2209) 06.08.13 00:37
Ох. Как же долго я ждал реабилитации. На полгодочка бы пораньше статью - и не было бы, уже ставшего историей, моего зачетного холивара c экспертом по технологическим вопросам ;) Уж и статьи нет, и эксперта нет, но осадочек то остался.

Сам холивар в аналах истории можно посмотреть по ссылке: http://web.archive.org/web/20121015050218/http://forum.infostart.ru/forum24/topic71483/
10. Антон Чарушкин (hulio) 06.08.13 06:17
(8) Dach, блокировка накладывается в начале записи движений и продолжает действовать до окончания транзакции
11. Гость 06.08.13 07:37
Начнем с того, что использовать «БлокироватьДляИзменения» имеет смысл, только если у регистра включен режим разделения итогов (если он выключен, то свойство не имеет смысла и будет просто игнорироваться)
.......
Несмотря на название, это свойство на самом деле ничего не блокирует, набор записей автоматически блокируются платформой при записи т.к. используется управляемый режим. Свойство лишь на время отключает разделитель итогов по данному набору измерений.


Пожалуйста, скажите откуда эта информация? Есть ли она в официальных источниках от фирмы 1С? Что значит "на время отключает разделитель итогов"?

Как можно просто так взять и временно удалить измерение Splitter из таблицы базы данных?

Очень был бы благодарен за ссылку на официальный источник, содержащий информацию о том, что "набор записей автоматически блокируются платформой при записи т.к. используется управляемый режим". Все что приходилось читать до этого имело другой смысл.
12. ффф ыыы (zqzq) 06.08.13 08:19
(11) HTone, у меня тот же вопрос, но такое впечатление, что автор на другом языке разговаривает.

Ещё раз по разделению итогов. Есть документ "Приход товаров", есть регистр Остатки (Измерение - Товар, Ресурс - количество). Документ приходует товары по регистру, никаких блокировок управляемых не делает. Пользователи бешено вводят эти документы. Если включить разделение итогов, то разные транзакции могут независимо одновременно обновлять таблицу итогов (Допустим записи (Splitter, Товар, Количиество) = (0, "Банан", 111+2), (1, "Банан", 0+5) {где 111 и 0 - остатки по ключу (Splitter, Товар)}). Если разделение итогов выключить, то даже если в СУБД все блокировки отключить, нельзя добавить 2 строки с одинаковыми ключами ("Банан" в данном случае) и записи будут добавлятся не параллельно а последовательно (т.е. запись одной и той же строки таблицы итогов).

Итого: разделение итогов никакой связи с управляемыми блокировками не имеет (см. также пост (2)).

Накладывается управляемая блокировка, а она работает с объектами 1С (а не таблицами СУБД), и если вы накладываете управляемую блокировку на пространство набор записей регистра, то уже не важно что будет заблокировано на уровне СУБД, т.к. встроенной менеджер блокировок 1С запретит изменять указанные записи регистра.
На уровне СУБД ничего заблокировано не будет, и менеджер блокировок не разрешит запись (в СУБД), пока (конкурирующая) блокировка не снимется. Ещё раз: причём тут разделение итогов?
13. Андрей Бурмистров (Andreynikus) 06.08.13 11:08
(11) HTone,
"Пожалуйста, скажите откуда эта информация?"
Я уж точно и не помню откуда это знаю, наверное еще со времен 1С:Эксперт
Дык вроде такие вещи должен знать каждый

"Есть ли она в официальных источниках от фирмы 1С?"
Наверняка где-то есть, посмотрите руководство разработчика.
А лучше мне вообще не верьте, я вру, как говаривал один умный доктор "все врут", берите и проверяйте сами :)
Тогда никаких вопросов не останется.
Опыт простой.
- ставим упр. режим блокировок на конфигурацию
- создаете регистр накопления, разделитель выключен
- делаем документ который делаает движения по этому регистру
- после записи движений ставим точку останова
- делаем и проводим копию 1-го документа (что бы был тот же набор записей)
- ждем 20 сек. и получаем ошибку по таймауту т.к. данный набор уже заблокирован

"Что значит "на время отключает разделитель итогов"?
То и значит.

Как можно просто так взять и временно удалить измерение Splitter из таблицы базы данных?"
Разделитель не удаляется, я же написал пример с 6 транзакциями, другие транзакции могут спокойно писать данные параллельно.
Это управляемая блокировка (а не СУБД), для того что бы учитывать или не учитывать разделитель, не обязательно удалять его из базы, в 1С конечно суровые ребята, но не настолько же :)
Это все происходит на уровне платформы.

"Все что приходилось читать до этого имело другой смысл"
Либо вы не то читали, либо неправильно это поняли.
Если сомневаетесь в чем-то, то никого не слушайте, какой бы авторитет вам этого не говорил, берите и проверяйте на практике.
14. ZLENKO.PRO (ZLENKO) 06.08.13 11:08
(7) rozer, Это будет "плохо"... Код проверки остатков надо размещать в модуле самого регистра в обработчике события "ПриЗаписи". Явная запись наборов записей в регистре крайне нежелательна, т.к. с высокой вероятностью может приводить к взаимоблокировкам при разном порядке записи регистров. Платформа сама запишет наборы и тогда сработает событие в котором проверим остаток.
15. ZLENKO.PRO (ZLENKO) 06.08.13 11:14
(13) Andreynikus, Автор прав - кто не верит - пусть сам проверит :-)
Зачем кому то что то доказывать ? Кому "надо" - поверит или проверит, а кому "не надо" - пусть остается при своем мнении. Бисера на всех не хватит...
16. Роман Озеряный (rozer) 06.08.13 11:17
(14)

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


дедлок может быть если Движения.ОстаткиТоваров.Записать() а Движения.Записать() - нет


Код проверки остатков надо размещать в модуле самого регистра в обработчике события "ПриЗаписи"


Спасибо Кэп :) Это как угодно но только когда записи уже в БД и здесь обсуждается КОНКРЕТНЫЙ пример КОНКРЕТНОЙ публикации ...
17. Андрей Бурмистров (Andreynikus) 06.08.13 11:24
(12) zqzq,
"Итого: разделение итогов никакой связи с управляемыми блокировками не имеет"


Если говорить только про разделение итогов, то да, его можно использовать и в автоматическом режиме.
Но данная статья не про это, она про свойство БлокироватьДляИзменения, и это свойство имеет смысл использовать только если используется управляемый режим, иначе будет ошибка.
Возможно вы подумали что разделитель итогов имеет смысл только в упр. режиме, это не так, я говорю именно про данное свойство, а не про разделитель итогов.
18. Андрей Бурмистров (Andreynikus) 06.08.13 11:41
(7) rozer,
Спасибо, да надо добавить, что-то запамятовал :)
19. Роман Озеряный (rozer) 06.08.13 11:49
(18) хотя (14) считает это "не кошерным" но решить вам как автору :)
20. Andrei Sevostyanov (Droni) 06.08.13 12:01
Спасибо за статью, очень позновательно.
21. ZLENKO.PRO (ZLENKO) 06.08.13 12:10
(19) rozer, согласен, что если все движения сразу записывать, то взаимоблокировок не возникнет (но с высокой степенью вероятности в коде была бы запись только нужного регистра) и платформа скорее всего даже второй раз не станет записывать наборы если они не изменятся, но явная запись движений наложит "преждевременную" блокировку на регистры и соответственно время в течение которого регистры будут заблокированы (до конца транзакции) будет больше.
22. ZLENKO.PRO (ZLENKO) 06.08.13 12:16
(17) Andreynikus, я для себя принял за правило использовать разделение итогов только для оборотных регистров, а для регистров остатков использовать разделение итогов только в исключительных случаях. Например, в "1С Розница" не используется контроль остатков, но высокая степень "параллельности" проведения чеков очень важна.
23. Роман Озеряный (rozer) 06.08.13 12:40
(21)
не наверное а точно...

метод Движения.Записать() записывает только те движения документа у которых установлен флаг "Записывать", при этом флаг в итоге снимается, что не приводит к повторной записи движений по окончании транзакции проведения.

дада "заблоченными" они останутся до окончания транзакции ну а для этого и переносят Движения.Записать() к концу процедуры. Просто обычно для "академических целей" по новой методе проведения движения пишут явно. Ну а в типовых там все сложней и конечно же более "оптимально" :)
24. ZLENKO.PRO (ZLENKO) 06.08.13 13:12
25. Владимир (V0fka) 06.08.13 16:03
Моделирую ситуацию. Есть регистр накопления, с включенным разделением итогов и управляемым режимом блокировки. В обработке проведения пишу туда набор. При этом специально пишу

ДвиженияРегистра.БлокироватьДляИзменения = Ложь;

Движения пишутся

Движения.Записать();

После этого провожу в другом сеансе такой же документ с таким же набором данных - и получаю конфиликт блокировок. Ну и вопрос: почему возникает блокировка?
26. Андрей Бурмистров (Andreynikus) 06.08.13 18:46
(25) V0fka,
Надо проверить что разделитель включен не только в конфигураторе, но и в режиме предприятия, это можно сделать через управление итогами.
Так же режим разделения итогов не работает в файловом варианте, т.к. там блокировка накладывается на таблицы.

Если не то и не другое, то пришлите выгрузку базы, надо будет посмотреть.
27. Сергей Толмачев (sss999) 07.08.13 09:19
Спасибо за понятное изложение.А можно еще добавить пример с запросом на контроль остатков,а то я смутно помню там порядок действий.Нужно открывать пособие разработчика и т.д.
28. Анатолий Бритько (headMade) 07.08.13 10:03
29. anton safer (safer_bwd) 07.08.13 10:08
1. Данное свойство нужно использовать, только если соблюдаются все 3 условия:
- транзакция выполняется в управляемом режиме
- у регистра включен режим разделения итогов
- используется новая методика контроля остатков (остатки контролируются после записи)


Андрей, спасибо за статью. Правильно я понимаю, что если для регистра отключено разделение итогов, то не зависимо от свойства БлокироватьДляИзменения платформа наложит блокировку по комбинациям измерений в записаном наборе?
30. Сергей Толмачев (sss999) 07.08.13 10:16
Я знаю где посмотреть,я говорю про эргономику статьи,статья должна иметь как можно меньше ссылок если есть такая возможность.
31. Гость 07.08.13 10:25
Разделитель не удаляется, я же написал пример с 6 транзакциями, другие транзакции могут спокойно писать данные параллельно.
Это управляемая блокировка (а не СУБД), для того что бы учитывать или не учитывать разделитель, не обязательно удалять его из базы, в 1С конечно суровые ребята, но не настолько же :)
Это все происходит на уровне платформы.

Спасибо за разъяснение. Еще раз перечитал статью, огрокал :)
Новой информацией для меня было то, что платформа в любом случае заблокирует данные после записи по измерениям + Splitter, даже если БлокироватьДляИзменения = Ложь. Может быть и читал об этом ранее но стерлось из памяти.
Все становится на свои места если немного перефразировать некоторые выражения в статье. В общем спасибо за ценную информацию.
32. ZLENKO.PRO (ZLENKO) 07.08.13 10:27
(29) safer_bwd, Правильно. Блокировка в любом случае будет наложена, но это будут разные типы блокировки.
33. Гость 07.08.13 10:31
(15) ZLENKO.PRO,
Автор прав - кто не верит - пусть сам проверит :-)
Зачем кому то что то доказывать ? Кому "надо" - поверит или проверит, а кому "не надо" - пусть остается при своем мнении. Бисера на всех не хватит...

Вы о чем вообще? Читателям становятся непонятны некоторые выражения в статье вроде "временно отключает разделитель итогов" и им подобные. Автор быстро дал разъяснения и все стало понятно. К тому же автор сам отмечает, что относительно БлокироватьДляИзменения много заблуждений и они довольно стойкие, подкрепленные другими источниками. Если не метать бисер, то старания по написанию подобных статей будут сведены на нет.
34. Владимир (V0fka) 07.08.13 10:45
(26) Andreynikus, не вижу где это в предприятии включается



База, естественнно, SQL-ная.
35. Андрей Бурмистров (Andreynikus) 07.08.13 11:13
(34) V0fka,
Зайди в управление итогами через толстый клиент
36. ZLENKO.PRO (ZLENKO) 07.08.13 11:16
(33) HTone, не хотел никого обидеть. Просто от автора статьи начали требовать доказательств... Даже в технических вопросах любая точка зрения субъективна, т.к. это точка зрения конкретного человека. Автор поделился своей точкой зрения - этого достаточно. Даже в официальных источниках нет абсолютной истины. Вот к примеру везде "пиарятся" управляемые блокировки, но мало кто говорит о том что СУБД MS SQL сервер сама принимает решение о наложении блокировок на уровне БД, а потом люди удивляются что вроде ж перевели на управляемые блокировки а все равно получаем кучу деадлоков. Или сколько было шума про то что теперь можно не удалять движения при перепроведении для уменьшения количества блокировок и якобы конфигурации типовые под это дело переделаны, по посмотрите в код типовых - почти все движения удаляются, но уже программно :-) Поэтому "никому не верь" - "доверяй, но проверяй" :-)
утюгчеловек; Andreynikus; +2 Ответить
37. aspirator 23 (aspirator23) 07.08.13 11:19
Новая методика контроля остатов говорит о том, что проверка остатков проверяется после записи в регистр.
Проверка остатков выполняется в процедуре ОбработкаПроведения в конце ее, после записей в регистр.
Процедура ОбработкаПроведения выполняется в транзакции, значит регистры все равно будут заблокированы, до окончания контроля. В чем выигрыш, чем если проверять в начале обработке ОбработкаПроведения (старая методика)? Или регистр доступен для чтения и позволяет выполнить чтение "новых" остатков другими документами раньше?
38. anton safer (safer_bwd) 07.08.13 11:20
(32) ZLENKO.PRO,

Владимир,
разные типы блокировки
можно поподробнее = ) или отошлите меня туда где можно покурить инфу)
Спасибо.
39. Владимир (V0fka) 07.08.13 11:52
(35) Andreynikus, разделитель включен и в предприятии, но всеравно получаю тот эффект, о котором писал выше. Отправил ссылку в личных сообщениях.
40. Андрей Бурмистров (Andreynikus) 07.08.13 15:33
(39) V0fka,
Моделирую ситуацию. Есть регистр накопления, с включенным разделением итогов и управляемым режимом блокировки. В обработке проведения пишу туда набор. При этом специально пишу

ДвиженияРегистра.БлокироватьДляИзменения = Ложь;

Движения пишутся

Движения.Записать();

После этого провожу в другом сеансе такой же документ с таким же набором данных - и получаю конфиликт блокировок. Ну и вопрос: почему возникает блокировка?

Дело в том, что вы делаете контроль остатков после записи, а для этого нужны все строки, получается что второй документ записал свои движения, но не может проверить остатки т.к. первый документ заблокировал свою строку в таблице итогов.
В реальной системе, при таких настройках может возникнуть дедлок описанный в данной статье, как раз для его предотвращения и нужно свойство "БлокироватьДляИзменения".
Если хотите убедится что при разделителе можно писать данные параллельно, тогда отключите контроль остатков.
41. Андрей Бурмистров (Andreynikus) 07.08.13 15:43
(37) aspirator23,
Описывать плюсы и минусы новой методики проверки остатков - это не цель данной статьи.
Но об этом можно почитать например здесь.
42. Елена Пименова (Bukaska) 07.08.13 15:50
(25) V0fka,
Моделирую ситуацию. Есть регистр накопления, с включенным разделением итогов и управляемым режимом блокировки. В обработке проведения пишу туда набор. При этом специально пишу

ДвиженияРегистра.БлокироватьДляИзменения = Ложь;

Движения пишутся

Движения.Записать();

После этого провожу в другом сеансе такой же документ с таким же набором данных - и получаю конфиликт блокировок. Ну и вопрос: почему возникает блокировка?


Что-то я не догоняю.. а Имя регистра где? Куда пишите.. конечно будет неизвестно что..
Тем более что там не записать, а Записывать() = истина - вроде так пишем данные в регистре..
А записать() - это немножко с другого объекта метод
43. Андрей Бурмистров (Andreynikus) 07.08.13 15:51
(29) safer_bwd,

Правильно я понимаю, что если для регистра отключено разделение итогов, то не зависимо от свойства БлокироватьДляИзменения платформа наложит блокировку по комбинациям измерений в записаном наборе?


Не совсем так. Разделитель итогов и свойство "БлокироватьДляИзменения" тут вообще не причем.
Если транзакция выполняется в управляемом режиме, то платформа всегда будет накладывать блокировку на тот набор записей который записывается.
Т.е. тут дело в том, в каком режиме работает транзакция, разделитель тут роли не играет.
44. Владимир (V0fka) 07.08.13 16:33
(40) Andreynikus, да, точно. Спасибо! За статью плюсую.
45. anton safer (safer_bwd) 08.08.13 09:13
Андрей,

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

// регистр ОстаткиТоваров Расход
Движения.ОстаткиТоваров.Записывать = Истина;
Для Каждого ТекСтрокаТабличнаяЧасть Из ТабличнаяЧасть Цикл
Движение = Движения.ОстаткиТоваров.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Склад = Склад;
Движение.Товар = ТекСтрокаТабличнаяЧасть.Товар;
Движение.Количество = ТекСтрокаТабличнаяЧасть.Количество;
КонецЦикла;

Движения.ОстаткиТоваров.БлокироватьДляИзменения = Истина;

// Далее код проверки остатков …
КонецПроцедуры


может быть так ?

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

// регистр ОстаткиТоваров Расход
Движения.ОстаткиТоваров.Записывать = Ложь;

Для Каждого ТекСтрокаТабличнаяЧасть Из ТабличнаяЧасть Цикл
Движение = Движения.ОстаткиТоваров.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Склад = Склад;
Движение.Товар = ТекСтрокаТабличнаяЧасть.Товар;
Движение.Количество = ТекСтрокаТабличнаяЧасть.Количество;
КонецЦикла;

Движения.ОстаткиТоваров.БлокироватьДляИзменения = Истина;

Движения.Записать();

// Далее код проверки остатков …
КонецПроцедуры
46. ZLENKO.PRO (ZLENKO) 08.08.13 11:13
(38) safer_bwd, я черпал инфу в основном на форуме (партнерском) разработчиков 1С. Если есть туда доступ, почитайте топики про управляемые блокировки.
47. anton safer (safer_bwd) 08.08.13 16:19
(46) ZLENKO.PRO, спасибо будем копать.
48. Ридван (утюгчеловек) 09.08.13 20:19
Статья внесла лишь сумятицу в мой и без того неокрепший после перехода "старая/новая методика". Буду придираться к словам, но, видимо, без этого никак. Ибо тема тонкая.
Но как быть, если например у регистра есть 2 регистратора, и один документ использует контроль остатков, а второй нет?
В этом случае нам как раз и пригодится свойство регистров накопления и бухгалтерии «БлокироватьДляИзменения».

БлокироватьДляИзменения - свойство набора записей, а не свойство регистра.

А вот Разделение итогов это уже свойство самого регистра. Поэтому
Это значит, что режим разделения итогов на регистр в целом сохраняется и если у других наборов измерений БлокироватьДляИзменения = Ложь, то они могут быть записаны параллельно.

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

Это звучит как "Если проезжать перекресток на кайене, то светофор зеленый, а если на калине - то красный. Даже если калина и кайен едут по перекрестку одинаково и одновременно"
49. Ридван (утюгчеловек) 09.08.13 20:21
Но если 1С это тоталитарная мистическая секта, созданная для порабощения адептов через разрушение их сознания, в чем я сильно сомневаюсь, то всё оукей.
50. Андрей Бурмистров (Andreynikus) 09.08.13 23:18
БлокироватьДляИзменения - свойство набора записей, а не свойство регистра.

Да это свойство набора записей, спасибо за поправку.

А вот Разделение итогов это уже свойство самого регистра

А вы не думали о том, что если бы БлокироватьДляИзменения вырубало разделитель для всего регистра (а не для набора записей как на самом деле), то оно было бы свойством регистра?

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


Давайте по пунктам, будем выбивать сумятицу из вашей головы, для этого статья и была написана :)
Разделение итогов есть свойство самого регистра, тут вы все правильно сказали, и свойство набора записей "БлокироватьДляИзменения" ни коем образом не выключает разделитель итогов у всего регистра, т.е. если вы установите "БлокироватьДляИзменения=Истина", то в свойствах регистра разделитель итогов все равно будет включен.
БлокироватьДляИзменения действует только на записываемый набор записей, прошу не путать набор записей со всем регистром.
Ваш пример с перекрестком и машинами не корректен, т.к. вы считаете что отключается разделитель на весь регистр, а он отключается только для записываемого набора, это возможно т.к. платформа ставит управляемую блокировку, т.е. на уровне СУБД разделитель всегда включен, а на уровне платформы БлокироватьДляИзменения выключает разделитель для записываемого набора. Т.е. это все достигается за счет управляемых блокировок, там разработчики резвятся как хотят, хотят учитывают разделитель, хотят не учитывают.

Но если 1С это тоталитарная мистическая секта, созданная для порабощения адептов через разрушение их сознания

Мне очень жаль ваше сознание, честно -)
И как уже было сказано выше, если вы мне не верите, то легко можете сами это проверить, к чему все эти громкие слова, вы же не в провинциальном театре -)
Пример с 6 транзакциями есть, воспроизвести его можно очень просто.
Если не затруднит, отпишитесь о результатах.
51. Ридван (утюгчеловек) 10.08.13 09:32
(50) Спасибо за столь сдержанный ответ на мой, возможно, не очень сдержанный вопрос. Вы - хороший человек.

Но осталось не понятно. Синтаксис-помощник ничего не знает о разделении итогов для набора записей. И если вдуматься в смысл этого свойства, то оно перестает быть абсурдным только для самого регистра.

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

Короче, если вдруг два предыдущих абзаца высказаны мной непрозрачно для восприятия - резюмирую:
У набора записей нет свойства разделения итогов.

Что касается примера, то повторить-то его можно. Но таким образом мы проверим не само утверждение "БлокироватьДляИзменения отключает свойство Разделения итогов у набора записей регистров", а возможные его следствия, исходящие из предположения о том, что разделение итогов у набора записей существует. Никто не станет отрицать, что такие же следствия можно получить не пользуясь сомнительным свойством НЗ. Спрашивается - зачем плодить сущности?

В отладчике таких свойств не видно. Свойство разделения итогов самого регистра остается монументально недвижимым.

Я ведь могу сказать что "Господь Бог свой дланью решает все вопросы блокировок черз свойство БлокироватьДляИзменения", и никто не проверит прав я или нет. Запустите в отладчике - проверьте.

Прошу прощения за образность - люблю я это дело =)
52. Андрей Бурмистров (Andreynikus) 10.08.13 10:52
(51) утюгчеловек,
Давайте оставим обзорность графоманам, мы с вами технические специалисты и все можем проверить на практике.
Я вот больше конкретику люблю, поэтому давайте говорить максимально предметно без размозни.

Насколько я понял, вас смущает формулировка "БлокироватьДляИзменения отключает свойство Разделения итогов у набора записей регистров".
Ок, можно сказать другими словами "БлокироватьДляИзменеия делает так, что при записи набора, управляемая блокировка не учитывает разделитель итогов для данного набора" может так понятнее?
Если что-то не написано в синтаксис-помощнике, это еще не значит что этого нет. Думаю для многих это не новость :)
Формально у набора записей нет свойства разделитель итогов, но по факту мы можем дать указание управляемой блокировке не учитывать разделитель для определенного набора. Вот такая загагулина.

"Никто не станет отрицать, что такие же следствия можно получить не пользуясь сомнительным свойством НЗ"

Почему же никто, я стану отрицать :)
Если мы используем контроль остатков после записи (о чем было сказано в начале статьи), то те же следствия вы никак другим способом не получите.

И на будущее хочу заметить что критика должна быть конструктивной, а не "это фигня потому что я так думаю что это фигня".
У меня нет желания вас в чем-то убеждать, цель обсуждения разъяснить непонятные моменты, а не кого-то переубедить.
Давайте так, если у вас нет доказательств того, что написанное в статье неправда, то о чем мы вообще говорим? Я ведь не просто написал свои мысли на эту тему, все это проверено практикой.
Если вы сомневаетесь проверьте.
53. Ридван (утюгчеловек) 10.08.13 14:55
(52) Тем не менее, полагаю, всё гораздо проще.
БлокироватьДляИзменения накладывает управляемую блокировку на все комбинации измерений в наборе записей. Это просто, понятно, это соответствует названию, это вписывается в реальность. При этом режим разделения итогов никак не трогается и не изменяется.
Поясните мне, чего я не учел и где противоречие?

Простите мою настойчивость.
Sibiryak; +1 Ответить
54. Андрей Бурмистров (Andreynikus) 10.08.13 16:41
Настойчивость качество хорошее :)

Но вы выдвигаете разные теории, никак не подтверждая их практикой. Вам лень взять конфигуратор в руки и проверить?

"БлокироватьДляИзменения накладывает управляемую блокировку на все комбинации измерений"

Главное ваша ошибка в том, что вы думаете будто данное свойство ставит управляемую блокировку, это не так.
Блокировку накладывает сама платформа т.к. мы работаем в управляемом режиме.
Как только вы пишите что-то вроде Движения.Записать(), тут же накладывается управляемая блокировка, автоматически, без вашего участия. Эта блокировка никак не зависит от разделителей, это стандартное поведение в управляемом режиме.
Но фишка в том, что это будет блокировка с учетом разделителя (если он есть конечно).
Т.е. блокировка на все комбинации измерений + разделитель. И в данном случае возможен дедлок описанный в статье.
А теперь подумайте сами, что надо сделать, что бы дедлока небыло?
55. Владимир (hogik) 11.08.13 01:25
(0)
"Главное предназначение данного свойства - предотвратить дедлок."(с)
Думаю, главное ;-) его предназначение - это обеспечить неизменность "общей" суммы по всем записям/строкам "разделенных" итогов до конца транзакции, где требуется "общий" итог по измерению. Т.е. не дать другой сессии вставить/изменить запись/строку "разделенного" итога, и тем самым изменить "общий" итог по измерению до завершения транзакций сессий, где "общий" итог уже прочитан.
56. Андрей Бурмистров (Andreynikus) 11.08.13 03:23
не дать другой сессии вставить/изменить запись/строку "разделенного" итога, и тем самым изменить "общий" итог по измерению до завершения транзакций сессий, где "общий" итог уже прочитан.


Да, при использовании БлокироватьДляИзменения решается эта задача, но это не главное предназначение этого свойства.
Описанную вам проблему можно решить вообще без БлокироватьДляИзменения, например простым запросом контроля остатков после записи, как только вы выполните этот запрос будет наложена блокировка по всем измерениям без учета разделителя и эти данные уже никто не сможет изменить.
Но как уже было неоднократно сказано ранее, в этом случае возможен дедлок и только для того, что бы его небыло мы пишем БлокироватьДляИзменения. В этом случае блокировка без учета разделителя будет наложена сразу при записи еще до контроля остатков.
57. Владимир (hogik) 11.08.13 04:47
(56)
"Описанную вам проблему можно решить ... простым запросом контроля остатков после записи, как только вы выполните этот запрос будет наложена блокировка по всем измерениям без учета разделителя и эти данные уже никто не сможет изменить."(с)

Андрей (Andreynikus).
А чего будет между записью и этим запросом? ;-)
58. Андрей Бурмистров (Andreynikus) 11.08.13 10:04
(57) hogik,
А чего будет между записью и этим запросом? ;-)

Будет блокировка с учетом разделителя. Это все написано в статье.
Если выполнить запрос остатков, будет блокировка без учета разделителя и она (блокировка) будет держаться до конца транзакции.
59. Владимир (hogik) 11.08.13 15:45
(58)
"Будет блокировка с учетом разделителя. "(с)
Андрей (Andreynikus).
Ключевое слово в (57) сообщении - МЕЖДУ. ;-)
А в это МЕЖДУ другие сессии "набросают" своих записей "разделенного" итога. И "общий" итог в базе данных, для рассматриваемой, сессии будет отличаться от её ожиданий. ;-)
Андрей.
Попробуйте применить свои рассуждения публикации для СУБД с нормальной ;-) реализацией уровней изоляции транзакций. Думаю, даже первая таблица будет иметь другой вид. А "главность" свойства изменится с Вашего взгляда/понимания на моё определение в (55) сообщении. Попробуем? ;-)
60. Андрей Бурмистров (Andreynikus) 11.08.13 17:15
А в это МЕЖДУ другие сессии "набросают" своих записей "разделенного" итога

В первой таблице показана как раз эта ситуация.

И "общий" итог в базе данных, для рассматриваемой, сессии будет отличаться от её ожиданий

О каких ожиданиях вы говорите? Пока небыло контроля остатков, транзакция ни на что не надеется.

Попробуйте применить свои рассуждения публикации для СУБД с нормальной ;-) реализацией уровней изоляции транзакций.

А чем вас MS SQL Server и READ COMMITED не устраивают? Когда это они стали не нормальными?

Думаю, даже первая таблица будет иметь другой вид

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


Вы в точности описываете ситуацию при которой будет дедлок.
И я, если честно, не понимаю чего вы не понимаете :)
Скажите с чем вы не согласны, четко и ясно, в 7 слов.
Если не получится, значит вы сами не знаете чего вы не понимаете :)
А если получится, то доказательства в студию. Аргумент "Потому что я так думаю" не принимается :)
61. Владимир (hogik) 11.08.13 17:59
(60)
Андрей (Andreynikus).
Зря Вы накаляете разговор. :-(
Займемся, пока, только этим текстом:
"А чем вас MS SQL Server и READ COMMITED не устраивают? Когда это они стали не нормальными?"(с)
В первой Вашей таблице транзакции не увидят вставляемые записи "разделенного" итога другой сессии до завершения транзакции при использовании "нормальной" реализации изоляции. И в этом случае платформа 1С должна использовать управляемую блокировку на измерение без учета разделителя, чтобы обеспечить последовательное выполнение транзакций в разных сессиях.



Блокировочный механизм
Принцип действия, в общем-то, ясен из названия - в основе лежит протокол двухфазной блокировки. Перед чтением или изменением объект (запись) блокируется. То есть другим транзакциям запрещается изменять или даже читать этот объект до тех пор, пока первая транзакция не закончит с ним работать.

Версионный механизм
Принцип действия версионности основан на том, что транзакция, изменяя данные, порождает новую копию (версию) данных, с которой и работает. Другим транзакциям эта версия не видна, до тех пор, пока первая не зафиксируется. При этом даже после фиксации первой транзакции, устаревшая версия какое-то время сохраняется для корректной работы транзакций, стартовавших до завершения работы первой, но еще не успевших зафиксироваться.

Read committed. Этот уровень изоляции несколько строже, чем в модели, основанной на блокировании. В блокировочнике, если читающая транзакция с уровнем изоляции read committed наткнется на уже измененный, но еще не зафиксированный объект, то она будет ожидать его изменения и прочитает уже измененные данные. В версионнике же читающий запрос, как правило, берет версию данных на момент начала запроса, поэтому выборка будет согласованной. При этом не важно, меняются ли данные в настоящий момент какой-либо посторонней транзакцией или нет.
62. Андрей Бурмистров (Andreynikus) 11.08.13 18:14
(61) hogik,
Зря Вы накаляете разговор. :-(

Прошу меня извинить, если чем-то вас задел.

В 7 слов вы явно не уложились -)
Есть 4 уровня изоляции, никакого "нормального" уровня нет. Я не могу оперировать терминами которые есть только в вашей голове, уж пардоньте ))
В управляемом режиме используется READ COMMITED, никаких других уровней изоляции, в том числе и "нормального" там нет.
Давайте без воды, четче. яснее.
63. Владимир (hogik) 11.08.13 18:24
(62)
Андрей (Andreynikus).
Еще раз повторю. Зря Вы накаляете разговор!
И читайте, пожалуйста, внимательно тексты собеседника.
Вот текст из моего (59) сообщения:
"... для СУБД с нормальной ;-) реализацией уровней изоляции транзакций."(с)
Ключевое слово в этом тексте - РЕАЛИЗАЦИЯ. А не НОРМАЛЬНОСТЬ уровней.
Специально привел тексты-цитаты в (61) сообщении из описаний СУБД. И это не в моей голове, а в различной РЕАЛИЗАЦИИ уровней изоляции в разных СУБД.
64. Андрей Бурмистров (Andreynikus) 11.08.13 18:31
(63) hogik,
Напишите пожалуйста, что с вашей точки зрения означает "СУБД с нормальной ;-) реализацией уровней изоляции транзакций"
65. Владимир (hogik) 11.08.13 18:39
(64)
Версионный механизм:
"... Другим транзакциям эта версия не видна, до тех пор, пока первая не зафиксируется."(с)
Что и используется в 1С 8.3 даже при использовании MS SQL.

P.S. (можно не читать).
Хотя и в блокировщиках можно обеспечивать вот так:
"The Advantage TPS uses the Read Committed Isolation Level to build robustness into database applications by only allowing visibility of committed data. While updates are being made within a transaction, the Advantage TPS hides those updates from other users until that data is committed. The uncommitted data is visible only to the application performing the transaction. The other applications view the data as it was before the transaction began. If the transaction is rolled back, the uncommitted data is never seen by any users other than the one who was performing the transaction. If the transaction is committed, the updated data becomes visible to all users at one time."(с)
66. Андрей Бурмистров (Andreynikus) 11.08.13 18:48
Бинго!
Вы оказывается про версионный режим толкуете, надо было сразу так и сказать, без всяких намеков.
Моя статья про 8.1 и 8.2, на 8.3 пока работают только самые отмороженные (и я им очень сочувствую), так что при написании статьи я про нее даже и не вспомнил, так же не вспомнил и про версионники (моя ошибка).
Сегодня проверю как это будет работать на 8.2 со скулем в режиме версионника.
67. Владимир (hogik) 11.08.13 19:05
(66)
"Вы оказывается про версионный режим толкуете"(с)
Андрей (Andreynikus).
Нет. ;-) Я толкую о том, что Вы хорошо описали возможности и потребности платформы. Но сделали ошибочный вывод. Т.к. платформа 1С ориентирована на работу с разными СУБД и инструменты самой платформы должны (так задумали разработчики) не зависеть от конкретной СУБД.
Для СУБД-блокировщика свойство "БлокироватьДляИзменения" имеет "полезный побочный эффект"(с) - "предотвратить дедлок"(с). Но, именно - ПОБОЧНЫЙ. А основной - описан в моём (55) сообщении данной темы.
68. Андрей Бурмистров (Andreynikus) 11.08.13 19:13
(67) hogik,
Я на 99.99% уверен что поведение будет одинаковым, но я привык проверять, а не доверять, если бы все оставляющие комментарии поступали так же, то вопросов было бы гораздо меньше, либо не было совсем. Поэтому я все таки проверю :)

Для СУБД-блокировщика свойство "БлокироватьДляИзменения" имеет "полезный побочный эффект"(с) - "предотвратить дедлок"(с). Но, именно - ПОБОЧНЫЙ. А основной - описан в моём (55) сообщении данной темы.

Вы абсолютно ошибаетесь в своем выводе, в (56) сообщении я вам ответил.

Сделайте и опишите эксперимент, который доказывает что я ошибаюсь.
69. Владимир (hogik) 11.08.13 19:23
(68)
"Сделайте и опишите эксперимент, который доказывает что я ошибаюсь"(с)
Андрей (Andreynikus).
Вы ошибаетесь не в "действиях" метода для СУБД-блокировщика, а в сути его основного назначения. ;-) Т.е. Вы долго нашу беседу воспринимали как то, что я подвергаю сомнению Ваши эксперименты. Нет - не подвергаю. Но, пытаюсь смотреть чуть-чуть шире на проблемы блокировщика и причины появления самого инструмента "разделенных" итогов. Пытаюсь...
70. Андрей Бурмистров (Andreynikus) 11.08.13 19:51
Суть нашего спора в том, что:
Вы считаете что БлокироватьДляИзменения предназначен в первую очередь для блокировки всех необходимых данных (что бы можно было прочитать остатки), и лишь во вторую очередь для предотвращения дедлока.

Я считаю прямо противоположное. БлокироватьДляИзменения предназначен для предотвращения дедлока, и лишь во вторую очередь для блокировки необходимых данных (что бы можно было прочитать остатки)


Давайте сначала примем вашу точку зрения и немного поразмыслим.
Из вашего утверждения можно сделать вывод, что если не использовать БлокироватьДляИзменения, то все необходимые нам данные не будут заблокированы, т.к. часть из них будет занята управляемой блокировкой с разделителем. Свойство ведь для этого нужно, что бы блокировать данные (с вашей точки зрения).
Отсюда следует, что заблокировать все строки по набору измерений, можно только если использовать данное свойство.
Т.е. если мы не используем БлокироватьДляИзменения, мы никак не можем заблокировать все нужные строки, ведь если бы могли, тогда зачем разработчики вообще делали это свойство.
Но в нашей реальности мы можем заблокировать все нужные нам строки и без БлокироватьДляИзменения, просто выполнив обычный запрос по остаткам.
Мораль, зачем делать данное свойство, если то же самое делается запросом контроля остатков?
71. Андрей Бурмистров (Andreynikus) 11.08.13 20:37
Наконец-то я добрался до истины :)
Мы с вами оба правы, но каждый прав только на половину.

В том случае, если используется версионный режим, БлокироватьДляИзменения предназначено в первую очередь для того, что бы заблокировать все нужные строки. Здесь вы правы, я этого не учел.
Здесь мое утверждение из (70) "мы можем заблокировать все нужные нам строки и без БлокироватьДляИзменения, просто выполнив обычный запрос по остаткам" было ошибочно. В случае с версионником это не работает и запрос не будет блокировать все нужные данные, мы можем их заблокировать только данным свойством.


В том случае, если используется блокировочник, БлокироватьДляИзменения используется в первую очередь для того, что бы предотвратить дедлок, т.к. блокировка и так обеспечивается запросом остатков. Здесь прав я.
То же самое написано в официальных источниках.


И кстати мы оба ошиблись, когда предположили что поведение платформы будет одинаковым при использовании версионника и блокировочника. Это еще раз доказывает что все нужно проверять самому на практике.


Спасибо за наводку, дополню статью новой информацией.
72. Владимир (hogik) 11.08.13 21:03
(71)
Андрей (Andreynikus).
И Вам спасибо за содержательную беседу.
Однако. ;-)
Я не утверждал, что:
"поведение платформы будет одинаковым при использовании версионника и блокировочника."(с)
Я написал, что:
"Т.к. платформа 1С ориентирована на работу с разными СУБД и инструменты самой платформы должны (так задумали разработчики) не зависеть от конкретной СУБД. "(с).
Понимая под "инструментами" - это то, что используется при написании алгоритмов в конфигурации. Т.е. код предметного программиста не должен отличаться при использовании платформы с различными СУБД.
73. ZLENKO.PRO (ZLENKO) 12.08.13 14:23
(72) Код в типовых решениях не должен отличаться, но поведение платформы отличается :-)
Причем поведение отличается очень существенно, я бы даже сказал принципиально отличается!
Использовать различие в поведении для оптимизации в каждом конкретном случае или нет ...
74. ZLENKO.PRO (ZLENKO) 12.08.13 14:40
Кстати в случае версионника я не до конца понимаю как будет вести себя платформа при использовании разделения итогов, поэтому я отключил возможность разделения итогов. Без разделения итогов будет наложена блокировка на уровне сервера приложений при записи и сохранится до конца транзакции, а другие транзакции будут читать свои версии данных без учета текущей транзакции, но писать не смогут из-за блокировки (имеется ввиду по тому же самому набору измерений). А вот если разрешить разделение итогов, то получается другие транзакции писать смогут, но что при этом будет происходить с итогами ?
75. Владимир (hogik) 12.08.13 16:02
Владимир (ZLENKO.PRO).
По (73) я не понял текст.
По (74) я думаю, что - без разницы. Т.е. если используется обсуждаемый метод то все сессии будут ждать завершения ранее начатых транзакций других сессий. Для ЛЮБОГО действия с данными базы данных. Естественно, и для чтения. ;-) Это уже написал в (61) сообщении темы. Т.е. платформа переводит достоинства "версионника" в недостатки "блокировщика". :-) Но, в НАШИХ задачах иначе нет возможности сделать... :-(
76. Ридван (утюгчеловек) 12.08.13 19:15
Умные люди всегда договорятся. При условии что знают, о чем идет речь.
Andreynikus; +1 Ответить
77. Андрей Бурмистров (Andreynikus) 12.08.13 20:27
(74) ZLENKO.PRO,
Кстати в случае версионника я не до конца понимаю как будет вести себя платформа при использовании разделения итогов

Если использовать БлокироватьДляИзменения, все будет нормально, поведение платформы не поменяется, будет управляемая блокировка по всем нужным записям, а потому от используемой СУБД это никак не будет зависеть.
Поведение будет отличаться только если разделитель итогов включен И БлокироватьДляИзменения=Ложь (не используется), но это не правильно, т.к. в любом случае будет ошибка:

Если используем блокировочник - будет дедлок
Если используем версионник - будут отрицательные остатки


Так что если делать как положено, разделитель итогов включен И БлокироватьДляИзменения=Истина, все будет хорошо :)

Как только появится время, я актуализирую статью с учетом новой информации.
hulio; hogik; +2 Ответить 3
78. Владимир (hogik) 12.08.13 22:50
(77)
"будет управляемая блокировка по всем нужным записям"(с)
Андрей (Andreynikus).
Думаю, имеет смысл нам в беседе использовать более точные термины/формулировки. Ведь к моменту "срабатывания" БлокироватьДляИзменения=Истина может вообще не быть записей "разделенного" итога по измерению. А общий принцип использования блокировок - это не запись/обновление и блокировка, а блокировка и только потом запись/обновление. Т.е. при использовании обсуждаемого ;-) свойства устанавливается управляемый блокировка на "абстрактный" ресурс - значение ключа Склад+Товар. К этому моменту никаких записей "разделенного" итога еще не создано из данной сессии. А в момент их создания управляемые блокировки не устанавливаются на записи "разделенного" итога по значению ключа Склад+Товар+Разделитель. Но, для СУБД-блокировщика устанавливаются блокировки самой СУБД на запись "разделенного" итога. Эти блокировки всегда устанавливаются, т.к. это есть суть реализации уровней изоляции транзакций для некоторых популярных ;-) СУБД-блокировщиков. Что всегда приведет к deadlock (в наших примерах!!!), если пытаться читать эти записи из другой сессии. И как с этим бороться? ;-) Способ один - не давать ИЗМЕНЯТЬ и ЧИТАТЬ множество записей "разделенного" итога более чем из одной сессии одновременно. Т.е. выполнять транзакции строго последовательно по одной. Что и достигается установкой УПРАВЛЯЕМОЙ блокировкой на "абстрактный" ресурс Склад+Товар. Данный подход успешно устраняет и проблемы в СУБД-версионнике, но в другом контексте проблемы. :-)
P.S.
Извините, что так длинно написал. И возможно, что не очень четко сформулировал. Но, готов уточнять и пояснять своё видение обсуждаемого вопроса в дальнейшей беседе данной темы форума.
79. Андрей Бурмистров (Andreynikus) 12.08.13 23:28
(78) hogik,
В данном контексте, под нужными записями я подразумеваю не строки таблицы в СУБД, а записи на уровне 1С т.е. ключ Склад+Товар.

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

Но все равно спасибо за уточнение, наверняка кому-то будет полезно.
80. Андрей Андреевич (nalivai-chai) 26.08.13 14:33
Вот замечательная статья про блокировки: http://1cexpo.ru/informacziya/27-blokirovki-dannyx-v-1spredpriyatii-8.html. Компетенции большей, чем для чтения текущей статьи не требуется.

Свойство "БлокироватьДляИзменений" работает как описано в справке для платформы. Устанавливает управляемую блокировку. Мы могли бы не использовать этого свойства и сами создать её. Результат был бы тот же.

А то, что в статье сформулировано как
Разделитель отключается только для данного набора измерений.
, есть не более чем результат наложенной блокировки.

(77) Andreynikus, Относительно написанного вами в комментарии (77), как вы считаете, можно ли сделать вывод, что "БлокироватьДляИзменения" при новой методике нужно использовать, даже если нет разделения итогов у регистра накопления? Например, в случае, когда используется "версионник" (СУБД)?
81. Андрей Бурмистров (Andreynikus) 26.08.13 16:05
(80) nalivai-chai,
Спасибо за вопрос, но давайте по порядку
Вот замечательная статья про блокировки:

Это не статья, это отрывок из книги "Переход от 8.0 к 8.1" спертный самым наглым образом, причем эти замечательные люди даже ссылку на источник не оставили.
И там описаны лишь азы и основы, азбука я бы сказал :)

Свойство "БлокироватьДляИзменений" работает как описано в справке для платформы. Устанавливает управляемую блокировку.

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

можно ли сделать вывод, что "БлокироватьДляИзменения" при новой методике нужно использовать, даже если нет разделения итогов у регистра

Если нет разделения итогов, использовать это свойство бессмысленно. Если нет разделителя, при новой методике и так все прекрасно работает, т.к. остатки сразу блокируются записью и вторая транзакция (не важно на блокировочнике или версионнике) не сможет ничего записать и будет ждать первую.
82. Андрей Андреевич (nalivai-chai) 27.08.13 01:34
Все здорово, все отлично в статье и выводы правильные и когда, как и где применять нужно доходчиво описано. И вам спасибо большое за это.

Только один момент как песок в глаза, это про "отключение разделителя".

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


и т.п.

Никаких отключений разделителей не происходит.

Свойство "БлокироватьДляИзменения" делает только одну вещь, как и написано в документации, и в ИТС (раздел 9.3.6), устанавливает управляемую блокировку по всем необходимым измерениям регистра для исключения взаимоблокировок или дэдлоков, как вам угодно.

На крайний случай, можно было бы сформулировать, например, так: "В результате установки управляемой блокировки, при записи набора с установленным свойством "БлокироватьДляИзменения" = Истина, регистр блокируется таким образом, как если бы у него было отключено использование разделителя".

Даже если "отключение разделителей" понимать как некоторую абстракцию, которая должна упростить понимание сути дела, то эта абстракция, как мне показалось сбивает только с толку. Может и не прав, не исключаю. Но у меня первая мысль, которая сверкнула в голове, "а зачем нужно отключать разделители разработчикам", когда у них есть управляемые блокировки. Хотя по большому счету, кто их знает, чем они там не шутят?

Хотя, наверно, надо думать, что свойство "БлокироватьДляИзменения" выросло из "разделителей". Не было бы разделителей, то свойство это гроша ломанного не стоило бы.
83. Андрей Бурмистров (Andreynikus) 27.08.13 08:08
(82) nalivai-chai,
Вы говорите ровно тоже самое что и я, просто другими словами :)

В результате установки управляемой блокировки, при записи набора с установленным свойством "БлокироватьДляИзменения" = Истина, регистр блокируется таким образом, как если бы у него было отключено использование разделителя

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

То что написано в справке, правда, но здесь ключевой момент это слова по всем необходимым измерениям регистра, т.к. управляемая блокировка поставится и без свойства, но она будет не по всем необходимым записям (т.к. учитывается разделитель).
Данная статья раскрывает сам механизм, показывает каким именно образом получается блокировка по всем необходимым записям.
А вам почему-то этот самый механизм, как раз самый ключевой момент, режет глаза :)
84. Андрей Андреевич (nalivai-chai) 27.08.13 09:13
(83) Andreynikus, если вы хотите сказать, что суть установки управляемой блокировки по всем необходимым измерениям при установке свойства "БлокироватьДляИзменения" заключается в отключении разделения итогов, то - это бред. И вообще, такое понимание вопроса затуманивает суть.

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

Можно не устанавливать свойство "БлокироватьДляИзменения" и создать явно блокировку по всем измерениям и их значениям. Результат будет тот же, только количество строк кода будет больше и думать нужно аккуратнее.

Скажите, пожалуйста, вы сами догадались про "отключение разделителя" или узнали из какого-то достоверного источника? Очень интересно.
85. Андрей Бурмистров (Andreynikus) 27.08.13 11:40
Andreynikus, если вы хотите сказать, что суть установки управляемой блокировки по всем необходимым измерениям при установке свойства "БлокироватьДляИзменения" заключается в отключении разделения итогов, то - это бред. И вообще, такое понимание вопроса затуманивает суть.

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

"на самом деле эффект похожий на "отключение разделителя" является следствием установки управляемой блокировки, все просто и ничего более"

Если честно, я тут не вижу особой разницы, для меня смысл одинаковый
Установить блокировку без учета разделителя = отключить разделитель для данного набора
Можете выбрать любую правую или левую часть, как вам больше нравиться, здесь я спорить с вами не будут :) Главный смысл который я хотел донести, что разделитель не работает для записываемого набора значений, можете назвать это явление как вам будет угодно.

Скажите, пожалуйста, вы сами догадались про "отключение разделителя" или узнали из какого-то достоверного источника?

Узнал от разработчика платформы, но если вам нужны доказательства, то вот комментарий сотрудника фирмы 1С
Ключевая фраза Свойство БлокироватьДляИзменения, грубо говоря, просто отключает разделитель итогов для того, чтобы не возник дедлок
nalivai-chai; +1 Ответить 1
86. Андрей Андреевич (nalivai-chai) 27.08.13 13:14
(85) Andreynikus, спасибо огромное.

Теперь всё встало на свои места.

Максим Радченко, сообщение 561730:
Свойство БлокироватьДляИзменения, грубо говоря, просто отключает разделитель итогов


Ключевая фраза "ГРУБО ГОВОРЯ" :). Вымучили из человека :).

Вопросов больше нет.

P.S. Но я бы не использвал понятие "отключает разделитель", фактически такого нет, разве что косвенно и "грубо говоря", это отвлекает от сути, вызывает ненужные вопросы.
87. ZLENKO.PRO (ZLENKO) 27.08.13 13:17
Участники дискуссии пошли искать истину про то "что на самом деле делает" ...
Но я думаю интереснее было бы если бы кто то рассказал непосредственно свой опыт использования сабжа вместо теоретических изысканий :-) Например, я считаю что в случае версионной СУБД разделение итогов и, соответственно, использование данного свойства смысла не имеет. Ваше мнение по этому поводу ?
88. Владимир (hogik) 27.08.13 16:19
(87)
"я считаю что в случае версионной СУБД разделение итогов и, соответственно, использование данного свойства смысла не имеет. "(с)

Владимир (ZLENKO.PRO).
А я считаю, что при наличии понятия итогов (любых) в схеме базы данных - не имеет смысла сама версионная СУБД. Т.к., в части работы с итогами, версионник ОБЯЗАН работать как блокировщик.
Это, типа, моё "теоретическое изыскание"... :-)
89. ZLENKO.PRO (ZLENKO) 27.08.13 17:04
(88) hogik, не могу с Вами не согласится. В теории так оно и есть - при расчете итогов нужны блокировки. Однако на практике получается что смысл в версионной СУБД есть :-) Роль блокировшика по сути выполняет сервер приложений 1С и этого нам достаточно, а вот СУБД, работающая в режиме блокировщика накладывает избыточные блокировки и вызывает в лучшем случае ожидание на блокировках СУБД. Так что версионные СУБД "рулят" !

P.S.: Проверено электроникой :-)
90. Владимир (hogik) 27.08.13 17:15
(88)
"Так что версионные СУБД "рулят" !"(с)

Владимир (ZLENKO.PRO).
Конечно - рулят. :-)
Только в других задачах, целях и алгоритмах: http://infostart.ru/public/157277/
Что касается избыточных блокировок в блокировщике, то имеет смысл вспоминать о других СУБД-блокировщиках. Которые не используют избыточных блокировок для решения собственных проблем с обеспечением уровней изоляции, как это делает "жестянка" MS SQL. :-)
91. ZLENKO.PRO (ZLENKO) 27.08.13 17:25
Что касается избыточных блокировок в блокировщике, то имеет смысл вспоминать о других СУБД-блокировщиках

(90) Опять же в теории..., а на практике как часто Вы видели у заказчика "другие" СУБД-блокировщики и какие именно применительно к 1С ? :-)
92. Владимир (hogik) 27.08.13 17:32
(91)
"Как часто Вы видели у заказчика "другие" СУБД"(с)
Владимир (ZLENKO.PRO).
Я и не смотрю, т.к. не работаю с 1С-продуктом... :-)
93. ZLENKO.PRO (ZLENKO) 27.08.13 17:38
(90) hogik, на практике нет реальной достойной альтернативы СУБД для 1С кроме как MS SQL уже даже по той простой причине что 1С всегда "затачивалась" под MS SQL и именно на ней работает наиболее эффективно. Для всех других СУБД нужны "танцы с бубном"...
94. Владимир (hogik) 27.08.13 18:10
(93)
"нет реальной достойной альтернативы СУБД для 1С кроме как MS SQL"(с)
Владимир (ZLENKO.PRO).
Верю. :-)
Вы используете 1С с MS SQL в "версионном" режиме?
95. ZLENKO.PRO (ZLENKO) 27.08.13 23:46
(94) Я использую файловый вариант 1С - для моих целей его достаточно :-)
97. ZLENKO.PRO (ZLENKO) 28.08.13 08:15
(96) Вы же спросили про меня - я ответил. Мои заказчики используют, преимущественно, MS SQL Server 2008/R2.
К сожалению 1С в версии до 8.3 не сделала поддержку версионного режима для MS SQL. Не нужно думать что Вы "самый умный" - в этом нет ни смысла ни необходимости :-)
98. Андрей Андреевич (nalivai-chai) 28.08.13 10:23
(92) hogik, видел базы на PostreSQL и слышал от коллег, что встрачались с 1С на Oracle. Во всех случаях, на этих СУБД работали какие-то другие приложения и были соответствющие люди (админы БД), которые шарили в СУБД.

Все СУБД хороши. У всех есть свои плюсы и минусы.

MS SQL - выделятся тем, что она самая простая в использовании, установил и поехали, конечно в MS SQL куча настроек, но для новичков достаточно её поставить с настройками по умолчанию, чтобы все хоть как-то, но работало и с лучшими показателями, чем на файловой СУБД (естественно при многопользовательской работе).

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

Про "ораклу" много слышал, что отличная СУБД, только также много особенностей.
Andreynikus; +1 Ответить
99. Владимир (hogik) 28.08.13 19:00
(97)
"Не нужно думать что Вы "самый умный" - в этом нет ни смысла ни необходимости..."(с)

Владимир (ZLENKO.PRO).
Подобные фразы требуют пояснения, либо аналогичного ответа с моей стороны.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа