Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Блокировка блокирует, хотя не должна
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.2 > Программирование управляемых форм 1С 8.2
Vofka
Есть документ с ТЧ "Материалы", в которой содержатся Номенклатура, Количество, Цена и Сумма. В обработке проведения есть такой код:

ТЧ = Материалы.Выгрузить();
Блокировка = Новый БлокировкаДанных;
НовыйОбъектБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиМатериалов");
НовыйОбъектБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
НовыйОбъектБлокировки.ИсточникДанных = ТЧ;
НовыйОбъектБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");        
Блокировка.Заблокировать();


Сам регистр ОстаткиМатериалов имеет измерения Номенклатура, ОтвественныйСотрудник и ресурсы Количество, Сумма.

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

Кто-то может в курсе почему один документ блокирует второй?
logist
А если режим блокировки "Разделяемый"?
Vofka
С разделяемым то же самое.

ЗЫ. Платформа, кстати, 8.2.14.537.
Ardi
"сообщая мне, что не может заблокировать таблицу"
Оно пишет какую именно таблицу не может заблокировать?
Vofka
Цитата(Ardi @ 27.04.12, 15:05) необходимо зарегистрироваться для просмотра ссылки
Оно пишет какую именно таблицу не может заблокировать?

Да
Цитата
Не удалось заблокировать таблицу '_Document15'.

Я не проверял, что это за таблица, но почему-то мне кажется, что это таблица проводимого документа.
Ardi
Что за задержка в сеансе?
Наверно правильней в документах по 10 тыс. строк сделать?
Batchir
Ну так Вы ж блокируете "РегистрНакопления.ОстаткиМатериалов", а ругается на таблицу документов.
Попробуйте в момент блокировки провести другой документ, который двигает по этому регистру, подозреваю что проблем не будет.
Ardi
Цитата(Batchir @ 27.04.12, 16:09) необходимо зарегистрироваться для просмотра ссылки
Ну так Вы ж блокируете

Ну так всё остальное что нужно тоже блокируется. Только в автоматическом режиме. И таблицы целиком.
И в момент постановки на паузу таблица документов уже почему-то перешла в режим блокировки.
ИМХО.
Batchir
Ну пауза я так понимаю это остановка в отладчике в момент когда идет блокировка регистра или команда предупреждения.

ИМХО скорее всего идет следующая последовательность
1. Начало общей транзакции перед записью и проведением документа.
2. Запись документа. В этот момент таблица блокируется, т.к. именно в момент записи появляется инфо о том что изменились данные.
3. Проведение документа. В этот момент таблица документов блокирована, разблокируется после завершения/отмены транзакции.
4. Окончание общей транзакции после записи и проведения документа. Таблица документов разблокирована.

если на этапе после 2 и перед 4 поставить паузу, то в этот период таблица документа заблокирована, т.к. были её изменения в транзакции
и любая попытка изменить в ней данные приведет к сообщению о блокировке.
Ardi
Запись документа и проведение - разные транзакции. ИМХО.
Иначе одновременное проведение не существовало бы.
alex040269
А без блокировки блокирует? Может еще где-то блокировка вкоде имеется или режим автоматический???
Batchir
Цитата(Ardi @ 27.04.12, 17:09) необходимо зарегистрироваться для просмотра ссылки
Запись документа и проведение - разные транзакции. ИМХО.

Да?
НачатьТранзакцию();
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
ЗафиксироватьТранзакцию();


А нажать кнопку нового документа "ОК" (запись с проведением) документ запишется если есть ошибки при проведении?
Нет. А событие ПриЗаписи вызывается и в этот момент идет запись документа в таблицу и таблица блокируется, но в событии ОбработкаПроведения идет откат. Как оказывается не записанным документ если запись и проведение не выполняются в единой транзакции? ХЗ, может я чего то не так говорю.
alex040269
Цитата(Batchir @ 27.04.12, 17:17) необходимо зарегистрироваться для просмотра ссылки
А событие ПриЗаписи вызывается и в этот момент идет запись документа в таблицу


ПередЗаписью()

Запись документ

ПриЗаписи()

.....

Завершение транзакции

Ardi
Batchir
Это не та транзакция.
Batchir
Я смотрю на ситуацию простым взглядом.
Если нажать на ОК (запись с проведением),
то вызываются последовательно события
ПередЗаписью()
ПриЗаписи()
ОбработкаПроведения()
Если на любом из этапов дать Отказ, то мы получим откат до исходного состояния.
Если это происходит не в единой транзакции, то как?

Последовательность действий, приводящая к взаимной блокировке:

Транзакция Т1 записывает документ в таблицу документов, устанавливая эксклюзивную блокировку.
Транзакция Т2 пытается записать документ и обновить записи в таблице. При этом она пытается установить эксклюзивную блокировку, но ей это не удается, т.к. на таблицу уже установлена эксклюзивная блокировка транзакцией Т1.
Транзакция Т2 ожидает, когда транзакция Т1 закончится и снимет установленную блокировку. Только после этого она может быть выполнена.
alex040269
Цитата(Batchir @ 28.04.12, 8:28) необходимо зарегистрироваться для просмотра ссылки
Транзакция Т1 записывает документ в таблицу документов, устанавливая эксклюзивную блокировку.
Транзакция Т2 пытается записать документ и обновить записи в таблице. При этом она пытается установить эксклюзивную блокировку, но ей это не удается, т.к. на таблицу уже установлена эксклюзивная блокировка транзакцией Т1.
Транзакция Т2 ожидает, когда транзакция Т1 закончится и снимет установленную блокировку. Только после этого она может быть выполнена.

Все это логично, НО 1с зачем-то сделали управляемые блокировки и управлять блокировками таблиц документов НЕЛЬЗЯ!
Да и блокироваться таблица документов должна вся только при добавлении НОВОГО документа, при изменении документа должна блокироваться только соответствующая запись. (во всяком случае так было еще в КДИППЕРЕ).
Batchir
Выдержка с ИТС:
Цитата
...
При разработке (или доработке) системы следует всегда использовать сформулированное выше правило: блокировка в транзакции должна изначально осуществляться с максимально необходимым уровнем изоляции. Это позволит полностью исключить возникновение таких взаимоблокировок в системе.

Типичной ошибкой в коде конфигурации, которая может приводить к возникновению взаимоблокировок данного вида, является неблокирующее чтение и последующая запись в рамках одной транзакции:
1. Автоматический режим:
а. Чтение без опции "ДЛЯ ИЗМЕНЕНИЯ" и последующая запись.
б. Чтение в объектной технике и последующая запись.
2. Управляемый режим:
Чтение без установки блокировки (либо с установкой разделяемой блокировки) и последующая запись.

Для возникновения взаимоблокировки данного вида необходимо одновременное выполнение следующих условий:
Операции чтения и записи происходят в рамках одной транзакции. Если чтение и запись происходят в разных транзакциях, то это не может быть причиной возникновения взаимоблокировок. Следует учитывать, что транзакция может быть неявной, то есть автоматически создаваться "1С:Предприятием" (например, при проведении документа).
Записывается тот же самый ресурс, который перед этим был прочитан. Если читается один ресурс, а записывается другой, то это не может быть причиной возникновения взаимоблокировки.
...
alex040269
Vofka , огласите решение, пожалста.
Vofka
alex040269, решения пока нету.

Но я забыл про один очень важный момент: я провожу эксперименты на файловой базе. Почему-то думаю, что на SQL оно себя будет вести по другому. О результатах отпишу (скорей всего после праздников).
alex040269
На файловой в любом случае блокируется ВСЯ таблица.
Vofka
Цитата(alex040269 @ 28.04.12, 16:36) необходимо зарегистрироваться для просмотра ссылки
На файловой в любом случае блокируется ВСЯ таблица.

Ну и я о том же... Но как оказалось блокируется ещё и таблица документов. На SQL может система ведет себя по умнее и блокирует только записи (в т.ч. в таблице документов). Я это тоже проверю smile.gif
Flexy
Цитата(Vofka @ 28.04.12, 15:39) необходимо зарегистрироваться для просмотра ссылки
На SQL может система ведет себя по умнее и блокирует только записи (в т.ч. в таблице документов). Я это тоже проверю smile.gif

Результат уже есть?
А то сейчас для меня актуально.
Vofka
Цитата(Flexy @ 16.05.12, 11:07) необходимо зарегистрироваться для просмотра ссылки
Результат уже есть?

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