О чем эта статья
В статье рассказывается об использовании конструкции “ДЛЯ ИЗМЕНЕНИЯ” языка запросов 1С. Данный материал будет особенно полезен тем, кто хочет разобраться с особенностями блокировок регистров при работе с информационной базой в варианте клиент-сервер.
Применимость
Материал статьи актуален для конфигураций, использующих текущие версии платформы «1С:Предприятие» редакции 8.3, при этом использующих автоматический режим блокировки управления данными.
Конструкция ДЛЯ ИЗМЕНЕНИЯ
При использовании автоматического режима блокировок чтение без опции ДЛЯ ИЗМЕНЕНИЯ и последующая запись в рамках одной транзакции может приводить к возникновению взаимоблокировок, вызванных использованием недостаточного уровня блокировки ресурса.
Конструкция ДЛЯ ИЗМЕНЕНИЯ используется, чтобы вместо разделяемой S-блокировки установить U-блокировку обновления, совместимость которой с другими блокировками хуже:
В таблице стоит знак «+», если блокировки на пересечении строки и столбца совместимы, «–» – в противном случае.
Рассмотрим кратко основные виды блокировок.
Разделяемые (S) блокировки позволяют одновременным транзакциям считывать ресурс. Пока для ресурса существуют S-блокировки, другие транзакции не могут изменять данные.
Блокировки обновления (U) предотвращают возникновение распространенной формы взаимоблокировки. В сериализуемой транзакции или транзакции с повторяющимся чтением транзакция считывает данные, запрашивает разделяемую (S) блокировку на ресурс, затем выполняет изменение данных, что требует преобразование блокировки в исключительную (X).
Если две транзакции запрашивают разделяемую блокировку на ресурс и затем пытаются одновременно обновить данные, то одна из транзакций пытается преобразовать блокировку в исключительную (X).
Преобразование разделяемой блокировки в исключительную потребует некоторого времени, поскольку исключительная блокировка для одной транзакции несовместима с разделяемой блокировкой для другой транзакции.
Начнется ожидание блокировки.
Вторая транзакция попытается получить исключительную (X) блокировку для обновления. Поскольку обе транзакции выполняют преобразование в исключительную (X) блокировку и при этом каждая из транзакций ожидает, пока вторая снимет разделяемую блокировку, то в результате возникает взаимоблокировка.
Чтобы избежать этой потенциальной взаимоблокировки, применяются блокировки обновления (U). Блокировку обновления (U) может устанавливать для ресурса одновременно только одна транзакция. Если транзакция изменяет ресурс, то блокировка обновления (U) преобразуется в исключительную (X) блокировку.
Исключительная (X) блокировка запрещает транзакциям одновременный доступ к ресурсу. Если ресурс удерживается исключительной (X) блокировкой, то другие транзакции не могут изменять данные.
Конструкция ДЛЯ ИЗМЕНЕНИЯ указывается в конструкторе запроса на закладке Дополнительно:
На этой же закладке указывается, какие конкретно таблицы следует блокировать, если в запросе используется несколько таблиц. Если не указывать, какие таблицы блокировать, то U-блокировка будет наложена на все таблицы, указанные в запросе, в том числе и те, которые не будут записываться в дальнейшем. Эти блокировки будут избыточными, могут создавать проблемы при параллельной работе нескольких пользователей.
В управляемом режиме блокировок описываемой проблемы не существует, поэтому конструкция ДЛЯ ИЗМЕНЕНИЯ ни на что не влияет.
PDF-версия статьи для участников группы ВКонтакте
Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.
Если Вы еще не вступили в группу – сделайте это сейчас и в блоке ниже (на этой странице) появятся ссылка на скачивание материалов.
Статья в PDF-формате
Вы можете скачать эту статью в формате PDF: Курсы-по-1С.рф – Материалы из курса по запросам – Конструкция ДЛЯ ИЗМЕНЕНИЯ.pdf
P.S.
Понимать, как работают запросы и уметь их строить - обязательный навык для всех, кто дорабатывает и внедряет 1С.
После курса Вы сможете:
- Строить сложные запросы с несколькими источниками данных
- Уверенно задействовать вложенные запросы и временные таблицы
- Использовать встроенный язык для обработки результатов запроса
- Учитывать особенности соединений и объединений нескольких таблиц.
- Разрабатывать запросы на уровне задач Аттестации 1С:Специалист по платформе.
Правильно я понял что инструкция ДЛЯ ИЗМЕНЕНИЯ повышает уровень изоляции транзакции до REPEATABLE READ с READ COMMITTED на уровне SQL сервера?
Добрый день!
Не совсем. Конструкция ДЛЯ ИЗМЕНЕНИЯ используется только в режиме автоматических блокировок. А в этом режиме применяются уровни изоляции транзакций REPEATABLE READ (для объектных сущностей – справочники, документы и т.д.) и SERIALIZABLE (для необъектных сущностей – регистры) – см. статью на ИТС Управление блокировками данных в транзакции
При использовании в тексте запроса конструкции ДЛЯ ИЗМЕНЕНИЯ в фактически исполняемом запросе на уровне MS SQL Server появится подсказка (хинт) UPDLOCK:
...
FROM
_Document1 T1 WITH(REPEATABLEREAD, UPDLOCK)
Не нашел ответа на просторах интернета по поводу конструкции для изменения. Может быть вы ответите….
Когда конструкция ДляИзменения встречается в запросе один раз по одной таблица то вопросов нет. Автоматическая блокировка до конца транзакции.
Но если у нас пакетный запрос и в разных пакетах идет обращение к одной и той же таблице то по какому правилу будет установлена блокировка… Если конструкция ДляИзменения есть хотя бы в одном пакете для таблицы. Если конструкция ДляИзменения есть во всех пакетах для одной и той же таблицы?
Если ДляИзменения стоит для таблицы в последнем пакете?
Например:
выбрать поле1
поместить т1
из документ.НужныйТип;
выбрать поле2
поместить т2
из документ.НужныйТип;
Где нужно для изменения?
Добрый день!
Блокировки устанавливаются в момент выполнения запроса, сбрасываются при окончании транзакции. Если запрос выполняется вне транзакции предложение ДЛЯ ИЗМЕНЕНИЯ игнорируется.
Т.е. вторая транзакция при чтении будет ожидать снятия блокировки, не сможет прочитать заблокированные данные до тех пор, пока не будет завершена первая транзакция, установившая блокировку.
“Блокировку обновления (U) может устанавливать для ресурса одновременно только одна транзакция. ”
Почему? Ведь, судя по таблице, блокировка обновления совместима с разделяемой.
Да, U-блокировка совместима с S-блокировкой (см. таблицу), они могут быть установлены совместно. Но U-блокировка не совместима сама с собой, поэтому одновременно на один и тот же ресурс такую блокировку может установить только одна транзакция. Поэтому такая блокировка и используется, чтобы избежать взаимоблокировок. Т.е. конструкция ДЛЯ ИЗМЕНЕНИЯ блокирует чтение данных, только если вторая транзакция также использует конструкцию ДЛЯ ИЗМЕНЕНИЯ. В противном случае произойдут такие же проблемы со взаимоблокировкой, как описывается в статье.
Спасибо!
“Блокировку обновления (U) может устанавливать для ресурса одновременно только одна транзакция.”
А в таблице совместимости блокировок указано, что блокировка обновления совместима с разделяемой…
Как это понимать?
Добрый день!
Это значит, что конструкция ДЛЯ ИЗМЕНЕНИЯ блокирует чтение данных только такими запросами, которые тоже используют конструкцию ДЛЯ ИЗМЕНЕНИЯ.
Добрый вечер.
Экспериментировал. Платформа 8.3.4.496 и субд POSTGRESQL.
Конфигурация работает в режиме обычного приложения.
Ситуация такая: в свойствах конфигурации стоит режим управления блокировкой – автоматический и управляемый.
Есть два документа, Д1 – упр режим блокировки, Д2 – авто.
Оба документа пишут расход в один регистр накопления(РН), у которого упр режим блокировкой данных, авто нельзя потому что Д1 тогда не будет проводится – система ругается.
Соответственно Д1 считывает данные из РН под надзором накладываемой управляемой блокировки, а у Д2 в запросе к РН стоит конструкция для изменения, в качестве блокируемой таблицы указан РН.
В такой ситуации УПР блокировки прекрасно работают – и явные, и сделанные через свойство РН – БлокироватьДляИзменения.
Не хочет работать сабж этой статьи. Я сперва грешил на РН режим управления блокировкой у РН.
Однако известно что в транзакции этот самый режим определяется аналогичным режимом старшей транзакции – иными словами при проведении Д2 набору записей РН должен присвоиться авто режим управления блокировкой – а значит конструкция Для Изменения должна сработать и после выполнения запроса должен заблокироваться вообще весь РН.
Скажите пожалуйста – почему не работает конструкция Для Изменения?
Режим “Автоматический и Управляемый” специально предназначен для перевода в управляемый режим отдельных объектов конфигурации . Методика перевода одного документа на управляемые блокировки должна быть следующей:
-Переводим конфигурацию в режим “Автоматический и Управляемый”
-Выставляем документу режим “Управляемый”
-Выставляем всем регистрам, которые двигаются этим документом режим “Управляемый”
-Дописываем необходимые явные блокировки в модулях наборов записей регистров (например, перед проверкой остатков).
Возможно, в Вашем случае ошибка заключается в том, что проверка остатков осуществляется не в модуле набора записей регистра, а в обработчике проведения документа. При этом явная блокировка на уровне сервера предприятия в коде этого обработчика не устанавливается.
Добрый вечер.
Василий Ханевич, спасибо за ответ.
Как оказалось я заблуждался в предыдущем сообщении. Эта конструкция языка запросов работает. Правда несколько иначе чем я представлял – блокируется не вся таблица регистра накопления, а только те данные которые выбираются.
Поставил документ Д2 на точку останова после выполнения запроса, текст которого содержит сабж этой статьи и попытался провести другой документ Д1 у которого данные совпадают с данными Д2. Эксперимент удался – система сообщила что произошел конфликт блокировок, а документы Д1 у которых данные не совпадают с данными Д2 при этом проводится.
Василий, раз уж вы заговорили насчет методики перевода одного документа на управляемые блокировки, то я не могу удержаться от такого вопроса:
В общем случае управляемые блокировки имеет смысл накладывать перед выполнением тех запросов, тексты которых содержат сабж этой статьи?
Добрый день!
В режиме управляемых блокировок конструкция ДЛЯ ИЗМЕНЕНИЯ игнорируется. А в режиме автоматических блокировок установка управляемых блокировок не произойдет. Зато будет работать эта конструкция. Также важно понимать, что управляемые блокировки не отменяют работу блокировок СУБД. Поэтому я бы рассматривал каждый такой случай отдельно.
Добрый день. Василий Ханевич.
Мне кажется вы не поняли мой вопрос из моего прошлого поста. Я имел ввиду следующее:
Допустим переводится в режим управляемых блокировок один или несколько документов. Предположим в процессе проведения встречаются запросы, тексты которых содержат конструкцию языка запросов “ДЛЯ ИЗМЕНЕНИЯ” и в ней указаны какие-нибудь остаточные регистры.
Поскольку в упр режиме эта конструкция не будет работать, нужно наложить управляемую блокировку перед выполнением запросов, о которых идет речь в предыдущем абзаце.
Это ведь общий случай при переводе документа(ов) на управляемые блокировки?
Про частные случаи я не говорю потому что они выявляются каждый по отдельности исходя контекста программного кода.
Я правильно понимаю ситуацию?
Еще раз добрый день!
Да, не понял Ваш прошлый вопрос. Теперь, когда Вы подробно все расписали, стало понятнее. Вы правильно говорите, единственное – я бы не ориентировался только на наличие конструкции ДЛЯ ИЗМЕНЕНИЯ в тексте запроса, может, она там ошибочно отсутствует. Чаще всего управляемые блокировки нужны будут в процессе проведения документов там, где нужно прочитать, а затем записать измененные данные в те же самые таблицы (контроль остатков).
Добрый день, Данияр!
Здесь мы лишь можем дать общие рекомендации (см. ответ от Василия).
Детально такие вопросы мы могли разобрать в рамках курса по Оптимизации производительности 1С.
Кстати, сейчас этот курс можно купить в комплектах с существенной скидкой: http://курсы-по-1с.рф/news/инвестируйте-в-себя-и-выиграете/
Добрый вечер Евгений Гилев.
Я читал эту новость, предложение заманчивое, и даже уже показал это предложение руководству фирмы, где я работаю, не знаю какое решение примет начальство.
Скажите подобные распродажи будут проводиться в будущем еще? Например в честь праздников, как текущая распродажа, насколько я понял это предновогодняя акция.
Добрый день!
Мы не часто проводим подобные мероприятия – обычно не чаще 1-2 раз в год.
Иногда спонтанно, без привязки к праздникам :)
Мне кажется, заметка неполна, поскольку не рассматривает причины отсутствия описанной проблемы в режиме управляемых блокировок, а также не демонстрирует аналог проблемы на управляемых блокировках.
Андрей, все-таки эта статья именно по конструкции “Для изменения”.
Чего-то другого здесь мы показывать и не планировали.
Повторюсь еще раз, детальнее о блокировках, производительности мы говорим в курсе по Оптимизации – http://курсы-по-1с.рф/ускорение-1с/
Первую строчку можно выделить большим и жирным шрифтом :)