v8: Ключевое слово ДЛЯ ИЗМЕНЕНИЯ
Автор статьи: Волшебник | Редакторы: Гений 1С, Tristan Последняя редакция №4 от 21.08.06 | |
Блокировка записей от считывания (от чтения!).
Она нужна, если в модуле проведения документа, например, сначала рассчитываются (получаются) остатки, на основе которых делаются расчеты и движения, влияющие на те же регистры (остатки).
Рассмотрим многопользовательский режим работы:
Процесс А: Начинает транзакцию. Считывает остатки (допустим получилось 10)
Процесс Б: Начинает транзакцию. Считывает остатки (получилось 10)
Процесс А: Контролирует остатки, выполняет расчеты (допустим, нужно списать 8),
Процесс А: Выполняет запись новых данных (10-8 = 2). Завершает транзакцию.
Процесс Б: Контролирует остатки (10 > 7), думает, что все ок. Выполняет расчеты (допустим, нужно списать 7)
Процесс Б: ОШИБКА: Он не может списать 7, поскольку в регистре уже не хватает остатка (там уже 2) после записи движений процессом А или после записи движений на складе образуется минус.
Чтобы процесс Б не ошибался в САМОМ КОНЦЕ своей работы, он должен подождать завершения работы процесса А и даже не считывать эти данные. Поэтому добавляем туда ДЛЯ ИЗМЕНЕНИЯ. Теперь картина выглядит так:
Процесс А: Начинает транзакцию. Считывает остатки (допустим получилось 10) с ключевым словом ДЛЯ ИЗМЕНЕНИЯ
Процесс Б: Начинает транзакцию. Пытается считать те же данные (получилось 10) ДЛЯ ИЗМЕНЕНИЯ, но вынужден подождать.
Процесс А: Контролирует остатки, выполняет расчеты (допустим, нужно списать 8)
Процесс А: Выполняет запись новых данных (10-8 = 2). Завершает транзакцию.
Процесс Б: Получает свежие данные из регистра (2)
Процесс Б: Контролирует остатки и сразу определяет нехватку (расчеты не выполняются). Отменяет транзакцию.
В предложении ДЛЯ ИЗМЕНЕНИЯ можно указать конкретные таблицы для блокировки (иначе будут заблокированы все, участвующие в запросе): таблицы верхнего уровня (не табличные части), виртуальные таблицы без параметров.
ВАЖНО:
- Если активна транзакция, то таблицы блокируются не только на
время выполнения запроса, а полностью до конца транзакции. Заметьте, что
запись объекта - тоже транзакция, поэтому если в ПередЗаписью или в
ПриЗаписи вызвать такой запрос, то до конца записи таблица будет
заблокирована!
Так написано в ЖКК и проверено на практике.
- В транзакции таблица, заблокированная через "ДЛЯ ИЗМЕНЕНИЯ"
блокируется на запись другими транзакциями и на чтение запросами,
содержащими "ДЛЯ ИЗМЕНЕНИЯ". Простые запросы, не содержащие "ДЛЯ
ИЗМЕНЕНИЯ", могут читать данные из заблокированным таким образом таблиц.
- На практике проверено, что "ДЛЯ ИЗМЕНЕНИЯ" работает не только с
регистрами, но и со справочниками, скорее всего работает и с другими
таблицами (документы, возможно даже константы)
- "ДЛЯ ИЗМЕНЕНИЯ" -
гибкий способ блокировки объектов, срок жизни которой совпадает со
сроком жизни транзакции, более мягкий, чем Заблокировать()
- В файловой версии блокируется вся таблица целиком, в SQL-версии -
только записи, участвующие в запросе.Если используется запрос
максимального или среднего значения по таблице, блокируется вся таблица
(удобно для получения уникального кода при альтернативной сквозной
нумерации).
Tristan: Все становится понятно из предложения "В предложении ДЛЯ ИЗМЕНЕНИЯ можно указать конкретные таблицы для блокировки (иначе будут заблокированы все, участвующие таблицыв запросе).
Т.е. при выполнении запроса:
"ВЫБРАТЬ
| *,
|ИЗ
| Справочник.Номенклатура
|ДЛЯ ИЗМЕНЕНИЯ";
При попытке считать данные элемента или интерактивно открыть форму элемента справочника будет вызвано исключение.