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




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

99 Comments

  1. vano-ekt

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

    Лучше так:

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

    Reply
  2. zqzq
    РегистрНакопленияНаборЗаписей.<Имя регистра накопления>.БлокироватьДляИзменения

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

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

    Чтение и запись.

    Описание:

    Тип: Булево.

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

    При попытке использования в автоматическом режиме блокировки вызывает исключительную ситуацию. После успешной записи документа свойство устанавливается в Ложь у всех наборов записей.

    При отмене транзакции значение свойства восстанавливается в состояние до транзакции.

    Значение по умолчанию Ложь.

    Доступность:

    Сервер, толстый клиент, внешнее соединение.

    Показать

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

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

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

    upd: Установка свойства разделение итогов приводит к реструктуризации таблиц ИБ — в таблицу итогов добавляется колонка «Splitter» как виртуальное измерение. Отключение свойства приводит к обратному эффекту (и ещё дублирующие записи должны сливаться с суммированием). Т. е. это довольно затратная операция. Можно проверить вызвав в отладчике функцию ПолучитьСтруктуруХраненияБазыДанных().

    Reply
  3. Трактор

    Ссылка на сайт ИТС крива. Правильная http://its.1c.ru/db/metod81#content:1393:1

    Reply
  4. Andreynikus

    (2) zqzq,

    Не очень понятно, что вы хотите сказать.

    Тем не менее, попробую ответить.

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

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

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

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

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

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

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

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

    Спасибо, Кэп 🙂

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

    Если я вас не так понял, то прошу поконкретнее формулировать свои вопросы.

    Reply
  5. Andreynikus

    (3) Трактор,

    Странно, проверял перед публикацией, видимо после модерации слетела

    Спасибо что написали, исправлю

    Reply
  6. ZLENKO

    Статья хорошая — автору «зачет»!

    Reply
  7. rozer

    конечно неплохо перед

    // Далее код проверки остатков …

    вставить движения.записать() а так статья оч. полезная для тех у кого нет доступа к «партнерке» 1с 🙂

    Reply
  8. Dach

    Очень доходчиво все изложено, спасибо автору. Вопрос — а фактически, когда транзакция будет завершена? То есть когда «заблокированный» набор записей станет доступным и начнут свои действия другие транзакции?

    Reply
  9. Новенький_2209

    Ох. Как же долго я ждал реабилитации. На полгодочка бы пораньше статью — и не было бы, уже ставшего историей, моего зачетного холивара c экспертом по технологическим вопросам 😉 Уж и статьи нет, и эксперта нет, но осадочек то остался.

    Сам холивар в аналах истории можно посмотреть по ссылке: http://web.archive.org/web/20121015050218/http://forum.infostart.ru/forum24/topic71483/

    Reply
  10. hulio

    (8) Dach, блокировка накладывается в начале записи движений и продолжает действовать до окончания транзакции

    Reply
  11. Гость
    Начнем с того, что использовать «БлокироватьДляИзменения» имеет смысл, только если у регистра включен режим разделения итогов (если он выключен, то свойство не имеет смысла и будет просто игнорироваться)

    …….

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

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

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

    Очень был бы благодарен за ссылку на официальный источник, содержащий информацию о том, что «набор записей автоматически блокируются платформой при записи т.к. используется управляемый режим». Все что приходилось читать до этого имело другой смысл.

    Reply
  12. zqzq

    (11) HTone, у меня тот же вопрос, но такое впечатление, что автор на другом языке разговаривает.

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

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

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

    На уровне СУБД ничего заблокировано не будет, и менеджер блокировок не разрешит запись (в СУБД), пока (конкурирующая) блокировка не снимется. Ещё раз: причём тут разделение итогов?

    Reply
  13. ZLENKO

    (7) rozer, Это будет «плохо»… Код проверки остатков надо размещать в модуле самого регистра в обработчике события «ПриЗаписи». Явная запись наборов записей в регистре крайне нежелательна, т.к. с высокой вероятностью может приводить к взаимоблокировкам при разном порядке записи регистров. Платформа сама запишет наборы и тогда сработает событие в котором проверим остаток.

    Reply
  14. Andreynikus

    (11) HTone,

    «Пожалуйста, скажите откуда эта информация?»

    Я уж точно и не помню откуда это знаю, наверное еще со времен 1С:Эксперт

    Дык вроде такие вещи должен знать каждый

    «Есть ли она в официальных источниках от фирмы 1С?»

    Наверняка где-то есть, посмотрите руководство разработчика.

    А лучше мне вообще не верьте, я вру, как говаривал один умный доктор «все врут», берите и проверяйте сами 🙂

    Тогда никаких вопросов не останется.

    Опыт простой.

    — ставим упр. режим блокировок на конфигурацию

    — создаете регистр накопления, разделитель выключен

    — делаем документ который делаает движения по этому регистру

    — после записи движений ставим точку останова

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

    — ждем 20 сек. и получаем ошибку по таймауту т.к. данный набор уже заблокирован

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

    То и значит.

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

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

    Это управляемая блокировка (а не СУБД), для того что бы учитывать или не учитывать разделитель, не обязательно удалять его из базы, в 1С конечно суровые ребята, но не настолько же 🙂

    Это все происходит на уровне платформы.

    «Все что приходилось читать до этого имело другой смысл»

    Либо вы не то читали, либо неправильно это поняли.

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

    Reply
  15. ZLENKO

    (13) Автор прав — кто не верит — пусть сам проверит 🙂

    Зачем кому то что то доказывать ? Кому «надо» — поверит или проверит, а кому «не надо» — пусть остается при своем мнении. Бисера на всех не хватит…

    Reply
  16. rozer

    (14)


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

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


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

    Спасибо Кэп 🙂 Это как угодно но только когда записи уже в БД и здесь обсуждается КОНКРЕТНЫЙ пример КОНКРЕТНОЙ публикации …

    Reply
  17. Andreynikus

    (12) zqzq,

    «Итого: разделение итогов никакой связи с управляемыми блокировками не имеет»

    Если говорить только про разделение итогов, то да, его можно использовать и в автоматическом режиме.

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

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

    Reply
  18. Andreynikus

    (7) rozer,

    Спасибо, да надо добавить, что-то запамятовал 🙂

    Reply
  19. rozer

    (18) хотя (14) считает это «не кошерным» но решить вам как автору 🙂

    Reply
  20. Droni

    Спасибо за статью, очень позновательно.

    Reply
  21. ZLENKO

    (19) rozer, согласен, что если все движения сразу записывать, то взаимоблокировок не возникнет (но с высокой степенью вероятности в коде была бы запись только нужного регистра) и платформа скорее всего даже второй раз не станет записывать наборы если они не изменятся, но явная запись движений наложит «преждевременную» блокировку на регистры и соответственно время в течение которого регистры будут заблокированы (до конца транзакции) будет больше.

    Reply
  22. ZLENKO

    (17) я для себя принял за правило использовать разделение итогов только для оборотных регистров, а для регистров остатков использовать разделение итогов только в исключительных случаях. Например, в «1С Розница» не используется контроль остатков, но высокая степень «параллельности» проведения чеков очень важна.

    Reply
  23. rozer

    (21)

    не наверное а точно…


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

    дада «заблоченными» они останутся до окончания транзакции ну а для этого и переносят Движения.Записать() к концу процедуры. Просто обычно для «академических целей» по новой методе проведения движения пишут явно. Ну а в типовых там все сложней и конечно же более «оптимально» 🙂

    Reply
  24. ZLENKO

    (23) rozer, логично.

    Reply
  25. V0fka

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

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

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

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

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

    Reply
  26. Andreynikus

    (25) V0fka,

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

    Так же режим разделения итогов не работает в файловом варианте, т.к. там блокировка накладывается на таблицы.

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

    Reply
  27. sss999

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

    Reply
  28. headMade

    (27) sss999,

    посмотрите в статье Методика оперативного проведения и управляемые блокировки там очень хорощо написано

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

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

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

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

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

    Reply
  30. sss999

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

    Reply
  31. Гость
    Разделитель не удаляется, я же написал пример с 6 транзакциями, другие транзакции могут спокойно писать данные параллельно.

    Это управляемая блокировка (а не СУБД), для того что бы учитывать или не учитывать разделитель, не обязательно удалять его из базы, в 1С конечно суровые ребята, но не настолько же 🙂

    Это все происходит на уровне платформы.

    Спасибо за разъяснение. Еще раз перечитал статью, огрокал 🙂

    Новой информацией для меня было то, что платформа в любом случае заблокирует данные после записи по измерениям + Splitter, даже если БлокироватьДляИзменения = Ложь. Может быть и читал об этом ранее но стерлось из памяти.

    Все становится на свои места если немного перефразировать некоторые выражения в статье. В общем спасибо за ценную информацию.

    Reply
  32. ZLENKO

    (29) safer_bwd, Правильно. Блокировка в любом случае будет наложена, но это будут разные типы блокировки.

    Reply
  33. Гость

    (15) ZLENKO.PRO,

    Автор прав — кто не верит — пусть сам проверит 🙂

    Зачем кому то что то доказывать ? Кому «надо» — поверит или проверит, а кому «не надо» — пусть остается при своем мнении. Бисера на всех не хватит…

    Вы о чем вообще? Читателям становятся непонятны некоторые выражения в статье вроде «временно отключает разделитель итогов» и им подобные. Автор быстро дал разъяснения и все стало понятно. К тому же автор сам отмечает, что относительно БлокироватьДляИзменения много заблуждений и они довольно стойкие, подкрепленные другими источниками. Если не метать бисер, то старания по написанию подобных статей будут сведены на нет.

    Reply
  34. V0fka

    (26) не вижу где это в предприятии включается

    База, естественнно, SQL-ная.

    Reply
  35. Andreynikus

    (34) V0fka,

    Зайди в управление итогами через толстый клиент

    Reply
  36. ZLENKO

    (33) HTone, не хотел никого обидеть. Просто от автора статьи начали требовать доказательств… Даже в технических вопросах любая точка зрения субъективна, т.к. это точка зрения конкретного человека. Автор поделился своей точкой зрения — этого достаточно. Даже в официальных источниках нет абсолютной истины. Вот к примеру везде «пиарятся» управляемые блокировки, но мало кто говорит о том что СУБД MS SQL сервер сама принимает решение о наложении блокировок на уровне БД, а потом люди удивляются что вроде ж перевели на управляемые блокировки а все равно получаем кучу деадлоков. Или сколько было шума про то что теперь можно не удалять движения при перепроведении для уменьшения количества блокировок и якобы конфигурации типовые под это дело переделаны, по посмотрите в код типовых — почти все движения удаляются, но уже программно 🙂 Поэтому «никому не верь» — «доверяй, но проверяй» 🙂

    Reply
  37. aspirator23

    Новая методика контроля остатов говорит о том, что проверка остатков проверяется после записи в регистр.

    Проверка остатков выполняется в процедуре ОбработкаПроведения в конце ее, после записей в регистр.

    Процедура ОбработкаПроведения выполняется в транзакции, значит регистры все равно будут заблокированы, до окончания контроля. В чем выигрыш, чем если проверять в начале обработке ОбработкаПроведения (старая методика)? Или регистр доступен для чтения и позволяет выполнить чтение «новых» остатков другими документами раньше?

    Reply
  38. safer_bwd

    (32) ZLENKO.PRO,

    Владимир,

    разные типы блокировки

    можно поподробнее = ) или отошлите меня туда где можно покурить инфу)

    Спасибо.

    Reply
  39. V0fka

    (35) разделитель включен и в предприятии, но всеравно получаю тот эффект, о котором писал выше. Отправил ссылку в личных сообщениях.

    Reply
  40. Andreynikus

    (39) V0fka,

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

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

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

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

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

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

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

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

    Reply
  41. Andreynikus

    (37) aspirator23,

    Описывать плюсы и минусы новой методики проверки остатков — это не цель данной статьи.

    Но об этом можно почитать например здесь.

    Reply
  42. Bukaska

    (25) V0fka,

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

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

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

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

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

    Что-то я не догоняю.. а Имя регистра где? Куда пишите.. конечно будет неизвестно что..

    Тем более что там не записать, а Записывать() = истина — вроде так пишем данные в регистре..

    А записать() — это немножко с другого объекта метод

    Reply
  43. Andreynikus

    (29) safer_bwd,


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

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

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

    Т.е. тут дело в том, в каком режиме работает транзакция, разделитель тут роли не играет.

    Reply
  44. V0fka

    (40) да, точно. Спасибо! За статью плюсую.

    Reply
  45. safer_bwd

    Андрей,

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

    // регистр ОстаткиТоваров Расход

    Движения.ОстаткиТоваров.Записывать = Истина;

    Для Каждого ТекСтрокаТабличнаяЧасть Из ТабличнаяЧасть Цикл

    Движение = Движения.ОстаткиТоваров.Добавить();

    Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

    Движение.Период = Дата;

    Движение.Склад = Склад;

    Движение.Товар = ТекСтрокаТабличнаяЧасть.Товар;

    Движение.Количество = ТекСтрокаТабличнаяЧасть.Количество;

    КонецЦикла;

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

    // Далее код проверки остатков …

    КонецПроцедуры

    Показать

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

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

    // регистр ОстаткиТоваров Расход

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

    Для Каждого ТекСтрокаТабличнаяЧасть Из ТабличнаяЧасть Цикл

    Движение = Движения.ОстаткиТоваров.Добавить();

    Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

    Движение.Период = Дата;

    Движение.Склад = Склад;

    Движение.Товар = ТекСтрокаТабличнаяЧасть.Товар;

    Движение.Количество = ТекСтрокаТабличнаяЧасть.Количество;

    КонецЦикла;

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

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

    // Далее код проверки остатков …

    КонецПроцедуры

    Reply
  46. ZLENKO

    (38) safer_bwd, я черпал инфу в основном на форуме (партнерском) разработчиков 1С. Если есть туда доступ, почитайте топики про управляемые блокировки.

    Reply
  47. safer_bwd

    (46) ZLENKO.PRO, спасибо будем копать.

    Reply
  48. утюгчеловек

    Статья внесла лишь сумятицу в мой и без того неокрепший после перехода «старая/новая методика». Буду придираться к словам, но, видимо, без этого никак. Ибо тема тонкая.

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

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

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

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

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

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

    Это звучит как «Если проезжать перекресток на кайене, то светофор зеленый, а если на калине — то красный. Даже если калина и кайен едут по перекрестку одинаково и одновременно»

    Reply
  49. утюгчеловек

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

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

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

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

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

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

    Давайте по пунктам, будем выбивать сумятицу из вашей головы, для этого статья и была написана 🙂

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

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

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

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

    Мне очень жаль ваше сознание, честно -)

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

    Пример с 6 транзакциями есть, воспроизвести его можно очень просто.

    Если не затруднит, отпишитесь о результатах.

    Reply
  51. утюгчеловек

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

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

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

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

    У набора записей нет свойства разделения итогов.

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

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

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

    Прошу прощения за образность — люблю я это дело =)

    Reply
  52. Andreynikus

    (51) утюгчеловек,

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

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

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

    Ок, можно сказать другими словами «БлокироватьДляИзменеия делает так, что при записи набора, управляемая блокировка не учитывает разделитель итогов для данного набора» может так понятнее?

    Если что-то не написано в синтаксис-помощнике, это еще не значит что этого нет. Думаю для многих это не новость 🙂

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

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

    Почему же никто, я стану отрицать 🙂

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

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

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

    Давайте так, если у вас нет доказательств того, что написанное в статье неправда, то о чем мы вообще говорим? Я ведь не просто написал свои мысли на эту тему, все это проверено практикой.

    Если вы сомневаетесь проверьте.

    Reply
  53. утюгчеловек

    (52) Тем не менее, полагаю, всё гораздо проще.

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

    Поясните мне, чего я не учел и где противоречие?

    Простите мою настойчивость.

    Reply
  54. Andreynikus

    Настойчивость качество хорошее 🙂

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

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

    Главное ваша ошибка в том, что вы думаете будто данное свойство ставит управляемую блокировку, это не так.

    Блокировку накладывает сама платформа т.к. мы работаем в управляемом режиме.

    Как только вы пишите что-то вроде Движения.Записать(), тут же накладывается управляемая блокировка, автоматически, без вашего участия. Эта блокировка никак не зависит от разделителей, это стандартное поведение в управляемом режиме.

    Но фишка в том, что это будет блокировка с учетом разделителя (если он есть конечно).

    Т.е. блокировка на все комбинации измерений + разделитель. И в данном случае возможен дедлок описанный в статье.

    А теперь подумайте сами, что надо сделать, что бы дедлока небыло?

    Reply
  55. hogik

    (0)

    «Главное предназначение данного свойства — предотвратить дедлок.»(с)

    Думаю, главное 😉 его предназначение — это обеспечить неизменность «общей» суммы по всем записям/строкам «разделенных» итогов до конца транзакции, где требуется «общий» итог по измерению. Т.е. не дать другой сессии вставить/изменить запись/строку «разделенного» итога, и тем самым изменить «общий» итог по измерению до завершения транзакций сессий, где «общий» итог уже прочитан.

    Reply
  56. Andreynikus
    не дать другой сессии вставить/изменить запись/строку «разделенного» итога, и тем самым изменить «общий» итог по измерению до завершения транзакций сессий, где «общий» итог уже прочитан.

    Да, при использовании БлокироватьДляИзменения решается эта задача, но это не главное предназначение этого свойства.

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

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

    Reply
  57. hogik

    (56)

    «Описанную вам проблему можно решить … простым запросом контроля остатков после записи, как только вы выполните этот запрос будет наложена блокировка по всем измерениям без учета разделителя и эти данные уже никто не сможет изменить.»(с)

    Андрей (Andreynikus).

    А чего будет между записью и этим запросом? 😉

    Reply
  58. Andreynikus

    (57) hogik,

    А чего будет между записью и этим запросом? 😉

    Будет блокировка с учетом разделителя. Это все написано в статье.

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

    Reply
  59. hogik

    (58)

    «Будет блокировка с учетом разделителя. «(с)

    Андрей (Andreynikus).

    Ключевое слово в (57) сообщении — МЕЖДУ. 😉

    А в это МЕЖДУ другие сессии «набросают» своих записей «разделенного» итога. И «общий» итог в базе данных, для рассматриваемой, сессии будет отличаться от её ожиданий. 😉

    Андрей.

    Попробуйте применить свои рассуждения публикации для СУБД с нормальной 😉 реализацией уровней изоляции транзакций. Думаю, даже первая таблица будет иметь другой вид. А «главность» свойства изменится с Вашего взгляда/понимания на моё определение в (55) сообщении. Попробуем? 😉

    Reply
  60. Andreynikus
    А в это МЕЖДУ другие сессии «набросают» своих записей «разделенного» итога

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

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

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

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

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

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

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

    Только вот пользы от такого думанья …

    Вы в точности описываете ситуацию при которой будет дедлок.

    И я, если честно, не понимаю чего вы не понимаете 🙂

    Скажите с чем вы не согласны, четко и ясно, в 7 слов.

    Если не получится, значит вы сами не знаете чего вы не понимаете 🙂

    А если получится, то доказательства в студию. Аргумент «Потому что я так думаю» не принимается 🙂

    Reply
  61. hogik

    (60)

    Андрей (Andreynikus).

    Зря Вы накаляете разговор. 🙁

    Займемся, пока, только этим текстом:

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

    В первой Вашей таблице транзакции не увидят вставляемые записи «разделенного» итога другой сессии до завершения транзакции при использовании «нормальной» реализации изоляции. И в этом случае платформа 1С должна использовать управляемую блокировку на измерение без учета разделителя, чтобы обеспечить последовательное выполнение транзакций в разных сессиях.



    Блокировочный механизм

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

    Версионный механизм

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

    Read committed. Этот уровень изоляции несколько строже, чем в модели, основанной на блокировании. В блокировочнике, если читающая транзакция с уровнем изоляции read committed наткнется на уже измененный, но еще не зафиксированный объект, то она будет ожидать его изменения и прочитает уже измененные данные. В версионнике же читающий запрос, как правило, берет версию данных на момент начала запроса, поэтому выборка будет согласованной. При этом не важно, меняются ли данные в настоящий момент какой-либо посторонней транзакцией или нет.

    Reply
  62. Andreynikus

    (61) hogik,

    Зря Вы накаляете разговор. 🙁

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

    В 7 слов вы явно не уложились -)

    Есть 4 уровня изоляции, никакого «нормального» уровня нет. Я не могу оперировать терминами которые есть только в вашей голове, уж пардоньте ))

    В управляемом режиме используется READ COMMITED, никаких других уровней изоляции, в том числе и «нормального» там нет.

    Давайте без воды, четче. яснее.

    Reply
  63. hogik

    (62)

    Андрей (Andreynikus).

    Еще раз повторю. Зря Вы накаляете разговор!

    И читайте, пожалуйста, внимательно тексты собеседника.

    Вот текст из моего (59) сообщения:

    «… для СУБД с нормальной 😉 реализацией уровней изоляции транзакций.»(с)

    Ключевое слово в этом тексте — РЕАЛИЗАЦИЯ. А не НОРМАЛЬНОСТЬ уровней.

    Специально привел тексты-цитаты в (61) сообщении из описаний СУБД. И это не в моей голове, а в различной РЕАЛИЗАЦИИ уровней изоляции в разных СУБД.

    Reply
  64. Andreynikus

    (63) hogik,

    Напишите пожалуйста, что с вашей точки зрения означает «СУБД с нормальной 😉 реализацией уровней изоляции транзакций»

    Reply
  65. hogik

    (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.»(с)

    Reply
  66. Andreynikus

    Бинго!

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

    Моя статья про 8.1 и 8.2, на 8.3 пока работают только самые отмороженные (и я им очень сочувствую), так что при написании статьи я про нее даже и не вспомнил, так же не вспомнил и про версионники (моя ошибка).

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

    Reply
  67. hogik

    (66)

    «Вы оказывается про версионный режим толкуете»(с)

    Андрей (Andreynikus).

    Нет. 😉 Я толкую о том, что Вы хорошо описали возможности и потребности платформы. Но сделали ошибочный вывод. Т.к. платформа 1С ориентирована на работу с разными СУБД и инструменты самой платформы должны (так задумали разработчики) не зависеть от конкретной СУБД.

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

    Reply
  68. Andreynikus

    (67) hogik,

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

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

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

    Сделайте и опишите эксперимент, который доказывает что я ошибаюсь.

    Reply
  69. hogik

    (68)

    «Сделайте и опишите эксперимент, который доказывает что я ошибаюсь»(с)

    Андрей (Andreynikus).

    Вы ошибаетесь не в «действиях» метода для СУБД-блокировщика, а в сути его основного назначения. 😉 Т.е. Вы долго нашу беседу воспринимали как то, что я подвергаю сомнению Ваши эксперименты. Нет — не подвергаю. Но, пытаюсь смотреть чуть-чуть шире на проблемы блокировщика и причины появления самого инструмента «разделенных» итогов. Пытаюсь…

    Reply
  70. Andreynikus

    Суть нашего спора в том, что:

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

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

    Давайте сначала примем вашу точку зрения и немного поразмыслим.

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

    Отсюда следует, что заблокировать все строки по набору измерений, можно только если использовать данное свойство.

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

    Но в нашей реальности мы можем заблокировать все нужные нам строки и без БлокироватьДляИзменения, просто выполнив обычный запрос по остаткам.

    Мораль, зачем делать данное свойство, если то же самое делается запросом контроля остатков?

    Reply
  71. Andreynikus

    Наконец-то я добрался до истины 🙂

    Мы с вами оба правы, но каждый прав только на половину.

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

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

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

    То же самое написано в официальных источниках.

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

    Спасибо за наводку, дополню статью новой информацией.

    Reply
  72. hogik

    (71)

    Андрей (Andreynikus).

    И Вам спасибо за содержательную беседу.

    Однако. 😉

    Я не утверждал, что:

    «поведение платформы будет одинаковым при использовании версионника и блокировочника.»(с)

    Я написал, что:

    «Т.к. платформа 1С ориентирована на работу с разными СУБД и инструменты самой платформы должны (так задумали разработчики) не зависеть от конкретной СУБД. «(с).

    Понимая под «инструментами» — это то, что используется при написании алгоритмов в конфигурации. Т.е. код предметного программиста не должен отличаться при использовании платформы с различными СУБД.

    Reply
  73. ZLENKO

    (72) Код в типовых решениях не должен отличаться, но поведение платформы отличается 🙂

    Причем поведение отличается очень существенно, я бы даже сказал принципиально отличается!

    Использовать различие в поведении для оптимизации в каждом конкретном случае или нет …

    Reply
  74. ZLENKO

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

    Reply
  75. hogik

    Владимир (ZLENKO.PRO).

    По (73) я не понял текст.

    По (74) я думаю, что — без разницы. Т.е. если используется обсуждаемый метод то все сессии будут ждать завершения ранее начатых транзакций других сессий. Для ЛЮБОГО действия с данными базы данных. Естественно, и для чтения. 😉 Это уже написал в (61) сообщении темы. Т.е. платформа переводит достоинства «версионника» в недостатки «блокировщика». 🙂 Но, в НАШИХ задачах иначе нет возможности сделать… 🙁

    Reply
  76. утюгчеловек

    Умные люди всегда договорятся. При условии что знают, о чем идет речь.

    Reply
  77. Andreynikus

    (74) ZLENKO.PRO,

    Кстати в случае версионника я не до конца понимаю как будет вести себя платформа при использовании разделения итогов

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

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

    Если используем блокировочник — будет дедлок

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

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

    Как только появится время, я актуализирую статью с учетом новой информации.

    Reply
  78. hogik

    (77)

    «будет управляемая блокировка по всем нужным записям»(с)

    Андрей (Andreynikus).

    Думаю, имеет смысл нам в беседе использовать более точные термины/формулировки. Ведь к моменту «срабатывания» БлокироватьДляИзменения=Истина может вообще не быть записей «разделенного» итога по измерению. А общий принцип использования блокировок — это не запись/обновление и блокировка, а блокировка и только потом запись/обновление. Т.е. при использовании обсуждаемого 😉 свойства устанавливается управляемый блокировка на «абстрактный» ресурс — значение ключа Склад+Товар. К этому моменту никаких записей «разделенного» итога еще не создано из данной сессии. А в момент их создания управляемые блокировки не устанавливаются на записи «разделенного» итога по значению ключа Склад+Товар+Разделитель. Но, для СУБД-блокировщика устанавливаются блокировки самой СУБД на запись «разделенного» итога. Эти блокировки всегда устанавливаются, т.к. это есть суть реализации уровней изоляции транзакций для некоторых популярных 😉 СУБД-блокировщиков. Что всегда приведет к deadlock (в наших примерах!!!), если пытаться читать эти записи из другой сессии. И как с этим бороться? 😉 Способ один — не давать ИЗМЕНЯТЬ и ЧИТАТЬ множество записей «разделенного» итога более чем из одной сессии одновременно. Т.е. выполнять транзакции строго последовательно по одной. Что и достигается установкой УПРАВЛЯЕМОЙ блокировкой на «абстрактный» ресурс Склад+Товар. Данный подход успешно устраняет и проблемы в СУБД-версионнике, но в другом контексте проблемы. 🙂

    P.S.

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

    Reply
  79. Andreynikus

    (78) hogik,

    В данном контексте, под нужными записями я подразумеваю не строки таблицы в СУБД, а записи на уровне 1С т.е. ключ Склад+Товар.

    Ваше сообщение понятно, Вы просто описали механизм(условно) работы управляемых блокировок, думаю многие и так с ним знакомы.

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

    Подразумевается что читатель обладает достаточной компетенцией.

    Но все равно спасибо за уточнение, наверняка кому-то будет полезно.

    Reply
  80. nalivai-chai

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

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

    А то, что в статье сформулировано как

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

    , есть не более чем результат наложенной блокировки.

    (77) Относительно написанного вами в комментарии (77), как вы считаете, можно ли сделать вывод, что «БлокироватьДляИзменения» при новой методике нужно использовать, даже если нет разделения итогов у регистра накопления? Например, в случае, когда используется «версионник» (СУБД)?

    Reply
  81. Andreynikus

    (80) nalivai-chai,

    Спасибо за вопрос, но давайте по порядку

    Вот замечательная статья про блокировки:

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

    И там описаны лишь азы и основы, азбука я бы сказал 🙂

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

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

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

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

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

    Reply
  82. nalivai-chai

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

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

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

    и т.п.

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

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

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

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

    Хотя, наверно, надо думать, что свойство «БлокироватьДляИзменения» выросло из «разделителей». Не было бы разделителей, то свойство это гроша ломанного не стоило бы.

    Reply
  83. Andreynikus

    (82) nalivai-chai,

    Вы говорите ровно тоже самое что и я, просто другими словами 🙂

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

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

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

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

    А вам почему-то этот самый механизм, как раз самый ключевой момент, режет глаза 🙂

    Reply
  84. nalivai-chai

    (83) если вы хотите сказать, что суть установки управляемой блокировки по всем необходимым измерениям при установке свойства «БлокироватьДляИзменения» заключается в отключении разделения итогов, то — это бред. И вообще, такое понимание вопроса затуманивает суть.

    Причину и следствие пытаетесь переставить местами:

    — вы говорите, что блокировка достигается отключением разделителя;

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

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

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

    Reply
  85. Andreynikus

    (84)

    Тут от меня неоднократно требовали дать ссылку на источник, если вдруг кому еще интересно

    Книга «Профессиональная разработка в системе «1С:Предприятие 8»» редакция 2012 года

    Глава 11. Учет движения средств Стр 612

    Чтобы избежать изменения итогов между моментом записи и моментом

    чтения остатков, еще до формирования и записи движений регистра

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

    в значение Истина. В этом случае в момент записи набора записей плат-

    форма отключит разделитель итогов в регистре.
    Таким образом, другая

    транзакция не сможет записать движения по тем же измерениям, что и

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

    движений будут получены правильные остатки из регистров.
    Reply
  86. hogik

    (118)

    Андрей (Andreynikus).

    В этой цитате мне больше понравился 😉 другой текст (не по теме «отключения»):

    «Таким образом, другая транзакция не сможет записать движения по тем же измерениям, что и текущая, до окончания проведения документа.»(с)

    Написано более кратко, чем я написал в (55)-ом сообщении. Но, суть одинакова…

    Reply
  87. Andreynikus

    (119) Ну да, все мы смотрим на мир через свои фильтры восприятия ))

    Reply
  88. Sibiryak

    (52)

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

    Ок, можно сказать другими словами «БлокироватьДляИзменеия делает так, что при записи набора, управляемая блокировка не учитывает разделитель итогов для данного набора» может так понятнее?

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

    Reply
  89. nytlenc

    (126)

    не нужно ничего менять. БлокировтьДляИзменения Как раз «отключает» режим разделения итогов а не «игнорирует». Т.к. другие объекты одновременно с блокирующим регистр объектом не могут добавлять новые записи.

    Reply
  90. Andreynikus

    (131)

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

    Читайте внимательно статью, там это описано в таблице.

    Reply
  91. Andreynikus

    (126)

    Вы правы, внес поправки в статью.

    Reply
  92. nytlenc
    Reply
  93. Andreynikus

    (136)

    У меня к вам только один вопрос.

    Вы проводили опыты на практике наблюдая при этом какие блокировки в каком случае и на что ставятся?

    Reply
  94. nytlenc

    (137) у меня к Вам встречный вопрос. Вы 1С опытным путём изучали? Ну — тоесть над каждой функцией и процедурой ставили эксперимент? Проверяли работу каждого свойства? Ну смешно же задавать такие вопросы — конечно нет. Зачем ставить опыты, когда русским по белому все написано на официальном ресурсе.

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

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

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

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

    а вот на счет того что «Игнорирует» лучше конечно оставить понятие «Отключает»

    Reply
  95. Andreynikus

    (138)

    конечно нет

    Тогда дальнейший диалог не имеет смысла.

    Reply
  96. nytlenc

    Нашел еще один аргумент против


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

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

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

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

    Простой пример:

    Режим разделения итогов у регистра накопления «Себестоимость» включен.

    Необходимо рассчитать себестоимость товара для списания.

    Если флаг БлокироватьДляИзменения = ЛОЖЬ то кто угодно в момент проведения может в регистр добавить новые записи.

    Таким образом может получиться так, что мы прочитаем себестоимость товаров, в следующий момент времени их кто то поменяет добавив поступление, а в следующий за этим момент времени мы добавляем списание себестоимости. И когда мы сформируем все движения окажется, что себестоимость рассчитана неверно. Чтобы этого избежать, необходимо выставить флаг БлокироватьДляИзменения в ИСТИНА отключив режим разделения итогов.

    И никаких «новых методик контроля остатов (остатки контролируются после записи)» здесь не нужно.

    Из этого вынужден подчеркнуть

    (139)

    Дальнейший диалог не имеет смысла.
    Reply
  97. Andreynikus

    (140)

    В описанном вами случае нужно перед чтением ставить явную управляемую блокировку.

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

    Reply
  98. nytlenc

    (141)

    Андрей я ни в коем случае не занимаюсь терроризированием и никак не пытаюсь уличить вас во вранье или незнании чего либо, а также не пытаюсь блеснуть своим умом и т.д. или показаться умнее других. Скорее наоборот, пытаюсь пополнить свой багаж знаний, чтобы правильно и рационально использовать предоставленные инструменты компании 1С. К сожалению в Интернете достаточно много противоречивой информации и хочется докопаться до истины, прежде чем принять к с ведению и использовать знания.

    Reply
  99. Andreynikus

    (142)

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

    Что бы докопаться до истины как раз и нужна практика. Я уже не однократно «обжигался» когда в документации написано одно, а работает по другому или написано не очень четко и разные люди одно и тоже трактуют по разному.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *