Продвинутый курс. Мастер-группа Q&A. Block 2
Мы собрали лучшие вопросы участников предыдущих потоков курсов, которые будут полезны вам при изучении 2-го блока.
1. Разделение итогов и их пересчет.
При разделении итогов удаление дублей записей осуществляется из конфигуатора. А в режиме предприятия в управлении итогами(полные возможности) есть кнопка пересчет. Она это делает? А программно это возможно?
2. Использование агрегатов.
За что лишили агрегатов регистр остатков?
В чем смысл режима агрегатов с выключенным использованием агрегатов?
3. Блокировка данных.
Момент начала блокировки при использовании метода Заблокировать ясен, а при использовании “НаборЗаписей”.БлокироватьДляИзменения=Истина нет?
При управляемых блокировках, если программист не устанавливал блокировок, что сделает система и в какой момент времени?
Правильно ли я понимаю, что если “запись данных” базируется на прочитанных данных то, то что прочитано, должно быть заблокировано от изменений?
Как блокируются данные при управляемых блокировках при объектном чтении?
Если я создал объект БлокировкаДанных, добавил в него элементы, Заблокировал(), а потом удалили какой-то элемент, то блокировка описанная этим элементом сохраниться?(а если после Заблокировать() добавить элемент блокировки?)
4. Получение набора записей.
Вы получаете набор движений по стоимости товара оператором НаборСТоимостиТоваров=Документ.ПолучитьОбъект().Движения.СтоимостьТоваров;
При получении объекта из БД будет считан весь объект целиком?
А нам нужны только движения по 1 регистру. Не вернее ли в этом случае получить движения запросом?
5. Период итогов для регистров.
В окне “Управление итогами” можно управлять периодом рассчитанных итогов регистров накопления и бухгалтерии.
Итоги в обоих регистрах вроде хранятся одинаково, т.е. итоги за текущий месяц хранятся началом следующего.
Сейчас сентябрь. Система предлагает по умолчанию установить период рассчитанных итогов для регистров накопления – 31.08.11, а для регистров бухгалтерии почему-то 30.09.11.
Хотя раз итоги в обоих регистрах хранятся одинаково, то и даты должны быть одинаковые…
Почему же они разные?
6. “Пересечение” настроек СКД.
При программном открытии отчета с установленным отбором возникает сообщение
Невозможно применить фиксированные настройки. Пересекаются элементы отбора.
Как заставить систему очистить пользовательские настройки?
7. Передача параметров в отчет СКД.
Как передавать параметры и отборы в отчет, построенный на СКД без создания формы отчета.
8. Расшифровка в отчетах.
Есть три отчета
Оборотно-сальдовая ведомость (ОСВ)
ОСВ по счету
Проводки по Дт Счета
Хочу наладить простенькую расшифровку
Что бы при клике на ОСВ открывался отчет ОСВПоСчету, и тут же при клике по отчету ОСВПоСчету, открывались проводки по Дт Счета
Проблема – расшифровка отчета “ОСВ по счету” не работает.
Если не активировали токен — посмотрите видео-инструкцию (видео N5)
Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись — напишите нам на e-mail поддержки.
Здравствуйте, Евгений!
Хотелось бы услышать, Ваше мнение по поводу правильного наложения блокировок в следующей ситуации:
Например, есть Проведённая Расходная накладная, в которой есть одна строка с “товаром1” в количестве “1” штука.
Обработка проведения документа выглядит следующим образом:
//******************************************************************************
Движения.ОстаткиНоменклатуры.Записать();
Блокирока = Новый БлокировкаДанных;
ЭлементБлокировки = Блокирока.Добавить(“РегистрНакопления.ОстаткиНоменклатуры”);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных(“Номенклатура”,”Номенклатура”);
Блокирока.Заблокировать();
………………
//******************************************************************************
Допустим “пользователь1” заходит в накладную и меняет позицию “Товар1” на “Товар2” и нажимает провести. Первым делом выполняется следующая строка кода:
//******************************************************************************
Движения.ОстаткиНоменклатуры.Записать();
//******************************************************************************
Если исходить из Вашего ответа №3, который записан в видео-уроке по блокировке данных, то не исключена следующая ситуация:
В момент выполнения выше-написанной строки происходит запись пустого набора (на момент записи очищаемые товары документа блокируются) и на остатке появляется “Товар1” в количестве “1” штука. После завершения строки кода “Записать() если блокировка с “товара1” снимается, тогда тут же “пользователь2” создаёт второй документ “реализация” с позицией “товар1” и проводит его списав с остатка данную позицию “товара1”.
Затем у “пользователя1” при выполнении дальнейших строк транзакции выходит ошибка и транзакция откатывается, в этом случае на остатке становится минус одна позиция “товара1”.
В лекциях Павла Белоусова, перед строкой Записать(), есть ещё вот такая строка:
//******************************************************************************
Движения.ОстаткиНоменклатуры.БлокироватьДляИзменения = Истина;
//******************************************************************************
Которая по идее устанавливает признак игнорирования режима разделения итогов и тем самым блокирует таблицу итогов, предотвращая ошибку в БД, в случаях который я выше описал в качестве примера.
Вопрос: с Вашей точки зрения, нужно ли писать строку “Движения.ОстаткиНоменклатуры.БлокироватьДляИзменения = Истина;” перед записью очищающего набора движений, или нет, для регистра накопления с включенным режимом разделения итогов???
Добрый день, Дмитрий!
Смоделировал Вашу ситуацию на клиент-сервеной ИБ (MS SQL Server).
Второй пользователь в этом случае останавливается на методе “Заблокировать”, и отваливается с ошибкой:
{Документ.Продажа.МодульОбъекта(18)}: Ошибка при вызове метода контекста (Заблокировать)
Блокирока.Заблокировать();
по причине:
Конфликт блокировок при выполнении транзакции:
Превышено максимальное время ожидания предоставления блокировки
То есть коллизии не возникает.
Вот код модуля объекта:
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.Остатки.Записать();
Если НЕ ДополнительныеСвойства.Свойство(“БезЗадержки”) Тогда
Предупреждение(“СТОП”);
КонецЕсли;
Блокирока = Новый БлокировкаДанных;
ЭлементБлокировки = Блокирока.Добавить(“РегистрНакопления.Остатки”);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.ИсточникДанных = Товары;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных(“Товар”,”Товар”);
Блокирока.Заблокировать();
Движения.Остатки.Записывать = Истина;
Для Каждого ТекСтрокаТовары Из Товары Цикл
Движение = Движения.Остатки.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Товар = ТекСтрокаТовары.Товар;
Движение.Количество = ТекСтрокаТовары.Количество;
КонецЦикла;
КонецПроцедуры
Это означает, что система при блокирует данные замещаемого набора записей (то есть в примере автоматически происходит блокировка по Товару1).
Таким образом, Движения.ОстаткиНоменклатуры.БлокироватьДляИзменения в данном случае избыточно.
И еще момент свойство “БлокироватьДляИзменения” никак не связано с режимом разделения итогов. Оно означает лишь, что при записи набора в базу данных будет произведена управляемая блокировка этих данных.
Здравствуйте, Евгений!
//**** Вы писали *****************************************
……………..
И еще момент свойство «БлокироватьДляИзменения» никак не связано с режимом разделения итогов. Оно означает лишь, что при записи набора в базу данных будет произведена управляемая блокировка этих данных.
//********************************************************
Спасибо за Ваш ответ. Для меня очень интересно слышать мнение таких “мегаафторитетных” людей как Вы в сообществе 1с.
Но как бы там не было, Павел Белоусов также достаточно афторитетен, и судя по тому как он отвечал на вопрос о блокировках, то у меня воспринимается, что свойство “БлокироватьДляИзменения” влияет на режим разделения данных. Чтобы не звучало голословно, привожу конкретные ссылки на ответы Павла Белоусова:
Ссылка №1. Назначение использования данного свойства.
Ссылка №2. Тут Павел привёл пример, что перед записью пустых движений регистра, нужно свойство “БлокироватьДляИзменения” устанавливать в значение “Истина”
PS: это я привёл два разных сообщения, из которых следует что свойство “БлокироватьДляИзменения” не просто создаёт управляемую блокировку, а ещё и делает некоторые действия с таблицей итогов.
И ещё момент: вопрос по работе данного свойства я спрашивал у Андрея Габец, который является тоже достаточно авторитетным в сообществе 1с, он как и Вы сказал что устанавливать данное свойство излишне перед записью очищающего набора. Потом я написал об этом на форуме, и вот што на данное сообщение ответил Павел:
ССЫЛКА №3
PSS: чтобы какие люди не говорили, система в любом случае является программой, и работает по вполне определённому алгоритму. И такого понятия что у разных специалистов разное мнение – быть так не должно.
Хотелось бы по настоящему до конца разобраться в данном вопросе. И если Павел не прав, то не могли бы Вы ему это объяснить? А то в недалёком будущем, не хотелось бы чтобы он занизил балы, за правильное решение на экзамене :)))
Добрый день, Дмитрий!
Внимательно ознакомился с ответами Павла Белоусова.
Однако, я настаиваю, что свойство БлокироватьДляИзменения нужно ровно для управляемой блокировки данных.
Описание в синтакс-помощнике очень точное, на него нужно ориентироваться.
Теперь поясню, что хотел сказать Павел Белоусов. Он говорит, что БлокироватьДляИзменения делает блокировку данных в таблице итогов в момент записи набора в ИБ.
Но если разделение итогов в регистре не используется, то по любой комбинации измерений и периоду в таблице итогов одна запись. Это так и есть.
И раз в момент записи набора в ИБ происходит блокировка этой записи, то и смысла в БлокироватьДляИзменения нет. А вот это не так.
Блокировка в момент записи длится только пока запись выполняется. А с помощью БлокироватьДляИзменения мы добиваемся блокировки до окончания транзакции – собственно это наша цель.
А теперь перейдем от теории к практике.
В выгрузке находится простейшая ИБ – http://ifolder.ru/30269632.
Загрузите ее в клиент-серверный вариант.
Обратите внимание – у регистра выключено разделение итогов.
Проводите документы под двумя пользователями.
Если свойство БлокироватьДляИзменения установлено, то будет происходить блокировка.
Если строку закомментарить, то блокировки не будет.
На экзамене правильным будет это свойство устанавливать для документов, которые реализуют новый способ контроля остатков – сначала запись, потом чтение.
Здравствуйте!
Спасибо, за пример… сейчас по тестирую.
Но всё же по поводу нужности или ненужности использования свойства БлокироватьДляИзменения…
Рассматриваю старую методику проведения “сначала чтение потом запись”. Вы пишете (2-ое Ваше сообщение сверху) что данное свойство избыточно для данного случая, Павел Белоусов же в лекциях и на форуме (http://devtrainingforum.v8.1c.ru/forum/thread.jsp?id=573209#573209) пишет что данное свойство нужно устанавливать до выполнения очищающей записи у набора движений.
Выходит Павел дезинформирует там всех??? Или я опять не правильно понял суть примера?
Добрый день, Дмитрий!
Спасибо за настойчивость!
Внимательно изучил пример Павла – на этот раз соглашусь с ним.
Более того, сейчас действительно проясняется связь режима разделения итогов и свойства “БлокироватьДляИзменения”.
Итак, представим, что есть регистр “Остатки” с включенным разделением итогов.
Допустим, в таблице итогов (по конкретному месяцу) образовались 2 строки с одинаковым набором измерений:
– Товар 1 5 (шт.) 1 (Splitter)
– Товар 1 10 (шт.) 2 (Splitter)
Возьмем проведенный документ, который фиксировал расход 2 шт. Товар 1. В документе меняем Товар 1 на Товар 2 и проводим.
Если будет использоваться такая схема проведения:
Движения.Остатки.Записать();
// Накладываем управляемую блокировку по данным документа
// Выполняем контроль остатков
// Записываем новые движения в набор записей
То система при выполнении Движения.Остатки.Записать() заблокирует только одну запись из таблицы итогов.
А если перед записью написать:
Движения.Остатки.БлокироватьДляИзменения = Истина;
То будут заблокированы обе записи.
При этом, если режим разделения итогов у регистра выключен, то задублироваться записи в таблице итогов не могут в принципе.
Итак, делаем вывод.
БлокироватьДляИзменения нужно устанавливать при записи пустых наборов в ИБ. Поскольку режим разделения итогов может изменить любой пользователь с административными правами.
Записал пожелание разобрать этот тонкий момент в курсе!
Спасибо!
Здравствуйте, ещё раз :))
В до гонку назрел ещё один вопрос, опять же по теме блокировок…
Существуют такие режимы блокировок:
1. Автоматический – в этом случае как я понял, в 1с менеджер блокировок не создаётся, а устанавливается в самой СУБД уровень изоляции REPEATABLE READ который является достаточно избыточным, но позволяет СУБД самой принимать решения, о том какие данные блокировать.
2. Управляемый – в этом случае в СУБД включают уровень изоляции READ COMMITTED который снимает избыточность блокировок на уровне СУБД но на уровне 1с, создаётся менеджер управляемых блокировок, и данные блокируются уже средствами платформы.
Теперь вопрос: А какой уровень изоляции СУБД нужно ставить в случае, если в 1с используется режим блокировок (Автоматический и Управляемый)?
Ведь если уровень изолции блокировок в СУБД поставить REPEATABLE READ тогда от блокировок средствами 1с толку не будет, ведь 1с, допустим может пропустить запись, а менеджером блокировок СУБД она всё равно будет заблокирована из-за высокого уровня изоляции, а если поставить уровень READ COMMITTED тогда получится, что те объекты на которые управляемая блокировка наложена, то они будут обрабатываться нормально, а те объекты которые не переведены на управляемые блокировки, то они на таком низком уровне изоляции СУБД могут нарушить целостность данных…
Хороший вопрос :)
И здесь я предположу (но, кажется, это единственный возможный вариант).
В режиме “Автоматический + Управляемый” функции управления блокировкой берет на себя сервер приложений.
То есть на уровне СУБД включается уровень изоляции “READ COMMITTED”, а сервер приложений эмулирует работу уровня изоляции “REPEATABLE READ” для автоматических блокировок.
А для управляемых блокировок производится “точная” блокировка данных.