Ловец дедлоков СУБД

Публикация № 1089832

Администрирование - Производительность и оптимизация (HighLoad)

Оптимизация дедлок deadlock СУБД MS SQL ЦУП Profiler.

Анализ простейшего дедлока СУБД в рабочей базе с использованием ЦУП (центра управления производительностью) и profiler MS SQL (Microsoft SQL Server). Эта статья будет полезна людям, изучающим вопросы оптимизации работы 1С, или тем, у кого возникают дедлоки в рабочей базе. UPD 09.07.2019 добавлено воспроизведение блокировки в случае установки управляемой блокировки перед чтением набора записей регистра сведений. UPD 10.07.2019 добавлена тестовая база с примером.

С недавнего времени я начала заниматься работами по оптимизации 1с, и решила написать несколько статей на эту тему, чтобы не забыть то, чему я научилась. Своеобразную базу знаний, поэтому если подобная задача уже где-то разбиралась, то прошу прощения. Заодно, возможно, кому-нибудь это поможет в работе. Любая критика статьи приветствуется.

Сегодня я разберу deadlock СУБД. 

Итак, имеется программа доработанная программа 1С Медицина.Больничная аптека 2.0. режим управления блокировки данных - управляемый, платформа 8.3.10.2252, режим совместимости 8.3.8. 

При проведении документов "Заказ поставщику" возникает deadlock на СУБД со следующим текстом:

Ошибка при вызове метода контекста (Записать): Ошибка при выполнении обработчика - 'ОбработкаПроведения': {РегистрСведений.ИзмененияЕдиницИзмеренияНоменклатуры.МодульМенеджера(72)}:

Ошибка при вызове метода контекста (Записать): Конфликт блокировок при выполнении транзакции: Microsoft SQL Server Native Client 11.0: Transaction (Process ID 87) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. HRESULT=80004005, SQLSrvr: SQLSTATE=40001, state=34, Severity=D, native=1205, line=1

Для начала настроим SQL profiler на сбор дедлоков. И довольно быстро ловим необходимое:

Видим, что дедлок возникает на одном ресурсе - InfoRg8072, по структуре данных видим, что это регистр сведений ИзмененияЕдиницИзмеренияНоменклатуры:

Таблица: РегистрСведений.ИзмененияЕдиницИзмеренияНоменклатуры, Имя таблицы хранения: InfoRg8072, Назначение: Основная

- поля:

   Период (Period)

   Номенклатура (Fld8073)

   ЕдиницаИзмерения (Fld8074)

   Документ (Fld8075)

   Ответственный (Fld8076)

   Ошибка (Fld8077)

   ОбластьДанныхОсновныеДанные (Fld385)

- индексы:

   ByPeriod

      Период + Номенклатура + ЕдиницаИзмерения + Документ (Period + Fld8073 + Fld8074 + Fld8075)

   ByDims

      Номенклатура + ЕдиницаИзмерения + Документ + Период (Fld8073 + Fld8074 + Fld8075 + Period) 

 

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

Посмотрим на содержимое блокировок процесса 1. Итак, смотрим на первую блокировку - U (блокировка обновления). 

Запрос:

 

SELECT TOP 1

T1._Fld385

FROM dbo._InfoRg8072 T1

WHERE ((T1._Fld385 = ?)) AND (T1._Fld8073RRef = ? AND T1._Fld8074RRef = ? AND T1._Fld8075_TYPE = 0x08 AND T1._Fld8075_RTRef = 0x000000B6 AND T1._Fld8075_RRRef = ?)

 

План:

|--Top(TOP EXPRESSION:((1)))                                                                       

      |--Clustered Index Seek(OBJECT:([HP_w_sql_001].[dbo].[_InfoRg8072].[_InfoRg8072_ByDims] AS [T1]), SEEK:([T1].[_Fld385]=[@P1] AND [T1].[_Fld8073RRef]=[@P2] AND [T1].[_Fld8074RRef]=[@P3] AND [T1].[_Fld8075_TYPE]=0x08 AND [T1].[_Fld8075_RTRef]=0x000000B6 AND [T1].[_Fld8075_RRRef]=[@P4]) ORDERED FORWARD) 

Ничего криминального не видно...

Смотрим дальше, еще одна блокировка U:

Запрос:

SELECT TOP 1

T1._Fld385

FROM dbo._InfoRg8072 T1

WHERE ((T1._Fld385 = ?)) AND (T1._Fld8075_TYPE = 0x08 AND T1._Fld8075_RTRef = 0x000000B6 AND T1._Fld8075_RRRef = ?)

План:

|   |--Top(TOP EXPRESSION:((1)))                                                                                                              

|        |--Index Seek(OBJECT:([HP_w_sql_001].[dbo].[_InfoRg8072].[_InfoRg8072_ByPeriod] AS [T1]), SEEK:([T1].[_Fld385]=[@P1]),  WHERE:([HP_w_sql_001].[dbo].[_InfoRg8072].[_Fld8075_RRRef] as [T1].[_Fld8075_RRRef]=[@P2] AND [HP_w_sql_001].[dbo].[_InfoRg8072].[_Fld8075_TYPE] as [T1].[_Fld8075_TYPE]=0x08 AND [HP_w_sql_001].[dbo].[_InfoRg8072].[_Fld8075_RTRef] as [T1].[_Fld8075_RTRef]=0x000000B6) ORDERED FORWARD) 

 

А вот тут уже  интереснее. 

Видно, что тут использовался индекс, поскольку оператор Index Seek, но посмотрев повнимательнее, видим, что seek идет только по разделителю данных, ([_Fld385]=[@P1]), а у после seek идет where, это означает, что данным полям индекс использовать не удалось и происходит сканирование данных. 

Почему не был использован индекс? Потому что в составном индексе крайне важен порядок следования полей. И если условия отбора есть в индексе, но не стоит в самом начале или идут не подряд, то индекс не может использоваться. В нашем случае есть вот такой индекс:

Номенклатура + ЕдиницаИзмерения + Документ + Период (Fld8073 + Fld8074 + Fld8075 + Period) 

А запросе у нас есть отбор только по полю Документ (Fld8075). А перед этим в составном индексе есть еще и поле Номенклатура и ЕдиницаИзмерения, поэтому данный индекс не может использоваться.

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

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

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

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

- индексы:

   ByPeriod

      Период + Номенклатура + ЕдиницаИзмерения + Документ (Period + Fld8073 + Fld8074 + Fld8075)

   ByDims

      Номенклатура + ЕдиницаИзмерения + Документ + Период (Fld8073 + Fld8074 + Fld8075 + Period) 

  

Мы видим, что есть индекс, где первым полем идет Fld8075 отсутствует, а значит происходит сканирование данных.   

Теперь давайте посмотрим код 1с:

Вот код, который отрабатывает при записи документа Заказ поставщику:

При выполнении строки 

НаборЗаписей.Записать(Истина);

Выполняется первый запрос. (использующий индексы)

При проведении документа выполняется вот этот код: 

При выполнении строки 

НаборЗаписей.Записать(Истина);

Выполняется второй запрос. (не использующий индексы)

Как видно, здесь не стоят отборы по номенклатуре и единицы измерения, а есть только отбор по документу, поэтому подходящего индекса нет, он не используется. 

Мы видим типичный дедлок захвата ресурса в разном порядке:

Первый пользователь захватывает ресурс 1 в регистре сведений, 
Второй пользователь захватывает ресурс 2 в регистре сведений, 
Дальше первый пытается захватить весь регистр (поскольку в плане запроса скан), но не может - натыкается на захват ресурса 2. 
Второй так же пытается захватить весь регистр, но не может, поскольку натыкается на захват ресурса 1. 
Итого - дедлок

Теперь решение этой проблемы.

Вариант 1.

Перенести измерение "Документ" наверх. В этом случае индекс будет строиться следующим образом:

   ByDims

     Документ + Номенклатура + ЕдиницаИзмерения + Период (Fld8075 + Fld8073 + Fld8074 + Period) 

Вариант 2.

Проиндексировать измерение "Документ". Тогда в добавиться дополнительный индекс такого вида:

   ByDims

    Документ + Период + Номенклатура + ЕдиницаИзмерения (Fld8075 + Period + Fld8073 + Fld8074)

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

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

UPD 09.07.2019

В комментариях  был задан хороший вопрос, а не возник ли дедлок по причине чтения в транзакции записей регистра, а затем его записи. Мол, это хрестоматийный пример дедока.

Но есть следующие проблемы.

1. Это пример дедлока на управляемой блокировке. А в моем примере блокировка СУБД

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

3. Для успокоения совести я провела следующий эксперимент. 

а) Убрала индексирование измерения "документ"

б) Добавила управляемую блокировку в код (по просьбам, установив отбор по и номенклатуре):

г) Провела два документа с разными данными в разных сессиях, и на одном из них поймала дедлок СУБД:

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

UPD 10.07.2019

Я подготовила для вас модельную базу, на которой воспроизводится дедлок. Там используется точно такой же код, который представлен в статье, специально, чтобы вы могли поупражнятся в оптимизации кода и установить какие угодно транзакции и блокировки. 
PS 
1. не забудьте развернуть базу в клиент-серверном варианте. 
2. Дедлок возникает, если поставить точку останова в строке 40 модуля документа заказ поставщику.

Скачать файлы

Наименование Файл Версия Размер
Ловец дедлоков СУБД:

.dt 136,88Kb
2
.dt 136,88Kb 2 Скачать

Специальные предложения

Лучшие комментарии
79. life-wayfarer 18.11.19 12:10 Сейчас в теме
(78)
77)Я знал что будет плохо, но не знал что так скоро. ©
Вы пишете - читаете и снова пишете в периодический регистр при проведении документа.
Причем с разными отборами.
Это толково. Так конечно никаких блокировок никогда не случится. Они все от смеха поумирают.


Это был сарказм. Код из базы которую выложил автор и никакого отношения к нему не имею. По моему скромному мнению очень показательный пример.
Остальные комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. AlX0id 08.07.19 09:59 Сейчас в теме
режим совместимости 8.3.8.
deadlock на СУБД

ээ.. а куда подевался Read Committed Snapshot Isolation?
3. PerlAmutor 124 08.07.19 20:18 Сейчас в теме
(1) Этот уровень изоляции работает только с обычными запросами (Новый Запрос()) и запросами в динамических списках. Если Вы поставите исключительную блокировку на чтение и запись и встанете под отладчиком, то это некоим образом не скажется на параллельной работе пользователей, они продолжат читать данные пока не вызовут код, где идет попытка установить точно такую же блокировку (на чтение или на запись).

От дедлока как раз и должна спасать явная установка управляемой блокировки в коде. Тогда вместо дедлока по прошествии 20 секунд, если этого времени не хватило на проведение документа, пользователю будет выдано исключение таймаута. Сами по себе управляемые блокировки не спасают от дедлоков на 100%. SQL сервер живет своей жизнью и от эскалации блокировок 1С его отговаривать не умеет.
45. AlX0id 10.07.19 10:56 Сейчас в теме
(3)
Этот уровень изоляции работает только с обычными запросами


Это утверждение, конечно же, неверно - потому как уровень изоляции RCSI прописывается в свойствах базы данных на уровне MSSQL. Ну или я не понимаю, что вы имеете в виду под словом "работает".
53. PerlAmutor 124 10.07.19 19:22 Сейчас в теме
(45) Я про возможные ожидания программиста 1С и того результата, который он получит. RCSI конечно же будет работать, если его включили, но видно это будет только при соблюдении определенных условий.
5. azazana 63 08.07.19 23:51 Сейчас в теме
(1) Read Committed Snapshot Isolation есть, но в этом случае ставится U-блокировка, а не S, поэтому строки блокируются в не зависимости от уровня изоляции транзакции
12. CSiER 30 09.07.19 05:48 Сейчас в теме
. режим управления блокировки данных - управляемый, платформа 8.3.10.2252, режим совместимости 8.3.8.

Итак, смотрим на первую блокировку - U (блокировка обновления).

(5)
Read Committed Snapshot Isolation есть, но в этом случае ставится U-блокировка, а не S, поэтому строки блокируются в не зависимости от уровня изоляции транзакции


Насколько мне известно, U-блокировка ставится в автоматическом режиме и наличии оператора "ДЛЯ ИЗМЕНЕНИЯ". RCSI точно включено (проверить можно запросом из статьи)?
46. AlX0id 10.07.19 10:59 Сейчас в теме
(12)
Насколько мне известно, U-блокировка ставится в автоматическом режиме и наличии оператора "ДЛЯ ИЗМЕНЕНИЯ". RCSI точно включено (проверить можно запросом из статьи)?

Я тут покопал более глубоко - и.. Нет, не только в автоматическом режиме.. Как раз-таки RCSI их и накладывает.
Вообще, вот эти две статьи во многом прояснили для меня механизм работы RCSI:
https://sqlperformance.com/2014/05/t-sql-queries/read-committed-snapshot-isolation
https://sqlperformance.com/2014/05/t-sql-queries/data-modifications-under-rcsi
61. CSiER 30 11.07.19 08:05 Сейчас в теме
(46)
тут покопал более глубоко - и.. Нет, не только в автоматическом режиме.. Как раз-таки RCSI их и накладывает.
Вообще, вот эти две статьи во многом прояснили для меня механизм работы

Статьи хорошие - там объясняется объединение снэпшотов (то есть запись/обновление/вставка в базу).

Мне не понятен конкретно вот этот абзац (с выборкой из базы с U-блокировкой):
Смотрим дальше, еще одна блокировка U:

Запрос:

SELECT TOP 1

T1._Fld385

FROM dbo._InfoRg8072 T1

WHERE ((T1._Fld385 = ?)) AND (T1._Fld8075_TYPE = 0x08 AND T1._Fld8075_RTRef = 0x000000B6 AND T1._Fld8075_RRRef = ?)
План:

| |--Top(TOP EXPRESSION:((1)))

| |--Index Seek(OBJECT:([HP_w_sql_001].[dbo].[_InfoRg8072].[_InfoRg8072_ByPeriod] AS [T1]), SEEK:([T1].[_Fld385]=[@P1]), WHERE:([HP_w_sql_001].[dbo].[_InfoRg8072].[_Fld8075_RRRef] as [T1].[_Fld8075_RRRef]=[@P2] AND [HP_w_sql_001].[dbo].[_InfoRg8072].[_Fld8075_TYPE] as [T1].[_Fld8075_TYPE]=0x08 AND [HP_w_sql_001].[dbo].[_InfoRg8072].[_Fld8075_RTRef] as [T1].[_Fld8075_RTRef]=0x000000B6) ORDERED FORWARD)
Показать
55. azazana 63 10.07.19 21:29 Сейчас в теме
(12) Да, абсолютно точно.
Насколько мне известно, U-блокировка ставится в автоматическом режиме и наличии оператора "ДЛЯ ИЗМЕНЕНИЯ". RCSI точно включено (проверить можно запросом из статьи)?

Это как разработчик может поставить эту блокировку. А сама СУБД вольна выбирать что хочет.
В данном случае у нас вначале читаются U блокировкой записи, а затем удаляются X блокировкой.
Вот тут хорошо описан этот вариант.
Стоит отметить, что поведение блокировок обновления (U) зависит от плана выполнения. В некоторых случаях, когда мы обновляем несколько записей, SQL Server может установить сперва на все строки блокировки обновления (U), а затем заменить их на монопольные блокировки (X). В других случаях, когда, например, мы обновляем только одну строку, которая является ключом кластерного индекса, SQL Server может сразу установить монопольную блокировку (X), без установки блокировки обновления (U).

https://infostart.ru/public/708360/
62. CSiER 30 11.07.19 08:09 Сейчас в теме
(55)
В данном случае у нас вначале читаются U блокировкой записи, а затем удаляются X блокировкой.

При снэпшотах пишущие не блокируют читающих как раз потому, что никакие блокировки при чтении не устанавливаются - чтение идет из снэпшота.
64. CSiER 30 11.07.19 09:04 Сейчас в теме
(55) U-блокировка устанавливается при выполнении удаления:
Rows Executes StmtText
---- -------- --------
2 1 Clustered Index Delete(OBJECT:([testdeadlock].[dbo].[_InfoRg38].[_InfoRg38_2] AS [T1]), OBJECT:([testdeadlock].[dbo].[_InfoRg38].[_InfoRg38_1] AS [T1]))
2 1 |--Top(ROWCOUNT est 0)
2 1 |--Index Scan(OBJECT:([testdeadlock].[dbo].[_InfoRg38].[_InfoRg38_1] AS [T1]), WHERE:([testdeadlock].[dbo].[_InfoRg38].[_Fld41RRef] as [T1].[_Fld41RRef]=[@P1]) ORDERED FORWARD)

В приложении трассировка с дедлоком и обычным проведением.
Нормальное проведение один пользователь
Дедлок
2. zinal 46 08.07.19 10:34 Сейчас в теме
Вы меня извините, но индексы и блокировки друг с другом не связаны.
Природа deadlock же состоит именно в порядке выполнения операций над отбираемыми (а не сканируемыми) строками.

Изменив план запроса, вы, видимо, сократили время блокировок и тем самым снизили вероятность взаимной блокировки. Но сама проблема никуда не делась, поскольку никакими индексами ее полностью убрать нельзя.
triviumfan; Fox-trot; +2 Ответить
4. PerlAmutor 124 08.07.19 20:31 Сейчас в теме
Я бы лишний раз подумал, прежде чем менять порядок полей в регистре или добавлять еще один индекс. Таким решением можно избавиться от одной редкой проблемы и получить себе ворох новых. Другие документы делающие движения в регистр могут начать это делать медленнее за счет еще одного индекса и за счет сломавшихся их собственных "оптимизированных" запросов.
6. zinal 46 08.07.19 23:55 Сейчас в теме
(4) Полностью согласен.
И, самое главное, причину взаимоблокировки новые индексы не устранят.
9. azazana 63 09.07.19 00:07 Сейчас в теме
(6) Устраняют. Неоптимальные запросы одна из основных причин избыточных блокировок. И, как следствие, дедлоков.
11. buganov 156 09.07.19 05:44 Сейчас в теме
(9)https://its.1c.ru/db/metod8dev#content:4051:hdoc:case1
Повышение уровня блокировки ресурса в рамках одной транзакции. Вот Ваш вариант в данном случае
13. CSiER 30 09.07.19 06:29 Сейчас в теме
(9) Думаю, в контексте данной статьи это утверждение истинно в случае не использования RCSI.
Если используется Read Committed, то блокировка возникает из-за разного порядка захвата ресурсов. Пусть для примера в регистре всего 2 записи. Первая транзакция сперва меняет первую запись, в этот момент вторая транзакция меняет вторую запись. Далее обе эти транзакции выполняют частичный скан таблицы - в этот момент и возникает deadlock. Добавив ещё один индекс по документу, Вы избавились от частичного скана, но проблема взаимоблокировки не устранили. Если попробовать провести два документа по 10к записей в табличной части, то ошибка должна воспроизвестись (из-за эскалации).

Сможете сделать cf с данным регистром, документом и обработкой проведения для тестирования (или выслать полный листинг обработки проведения)?

Подписки какие-то по данному документу имеются?
68. azazana 63 11.07.19 13:30 Сейчас в теме
(13) Добавила модельную базу, можете воспроизвести.
69. CSiER 30 11.07.19 16:36 Сейчас в теме
(68), спасибо - уже воспроизвёл (см. комментарий 64).
Посмотрел Ваше решение - при больших объемах (документы более 10к строк) эскалации нет, вариант рабочий (хотя и придётся обслуживать доп. индекс).
При этом сама структура РС мне не нравится - возможно, стоило сделать документ регистратором. Код доверия не вызывает (например, в "ДвиженияДокументовПоРегистру" после установки отборов нет чтения регистра; движения в регистр попадают при записи, а не при проведении; период движения - текущая дата, а не дата документа или хотя бы дата сеанса).
71. azazana 63 11.07.19 18:21 Сейчас в теме
(69) Не спорю, у меня код доверия тоже не вызывает.
Я этот бизнес-процесс почти не знаю, но вроде бы идея в том, что вначале документ записывается, потом номенклатура в этом документе проверяется другими лицами и, если есть ошибка в номенклатуре (в названии или единице измерения), то меняется регистр сведений, выставляется флаг Ошибка = Истина. А потом третьи лица исправляют ошибки и проводят документ.
8. azazana 63 09.07.19 00:04 Сейчас в теме
(4) А я подумала. Это была доработка в конфигурации, я проверила, где именно она используется и каким образом. Именно поэтому отмела первый вариант, потому что в этом случае один из часто использующихся запросов будет выполнятся медленнее. А проблема на самом деле была очень нередкой, она возникала при каждом параллельном проведении документа "Заказ поставщику". То есть даже два пользователя не могли одновременно проводить документы с разными данными.
7. azazana 63 08.07.19 23:57 Сейчас в теме
(2) Вы меня извините, но связаны. Неоптимальные запросы одна из причин избыточных блокировок и как одно из следствий - дедлоков. Про это можно почитать, например, вот тут:
https://its.1c.ru/db/metod8dev#content:5842:hdoc
10. buganov 156 09.07.19 05:41 Сейчас в теме
Статья не совсем полная, как мне кажется. В начале указано, что при проведении документов возникает взаимоблокировка. То есть в одном сеансе проведение вызывает взаимоблокировку?
И еще, я лично ожидал увидеть здесь природу дедлока, т.е. не просто показ графа, а именно природу возникновения. Например, из-за разного порядка записи движений, пересечения блокируемых полей в разном порядке и т.п. А в статье только профайлер, ЦУП и, как мне кажется, не совсем верные выводы о том, что нужно делать. Действительно, Вы уменьшили время выполнения запроса, но не решили тем самым проблему, а просто снизили вероятность возникновения взаимоблокировки.
Кстати, в Вашем случае вполне вероятно помог бы отказ от объектного чтения регистра в процедуре УдалитьПризнак...
и наложением исключительной блокировки перед заполнением.
14. nytlenc 09.07.19 07:06 Сейчас в теме
Для начала настроим SQL profiler на сбор дедлоков. И довольно быстро ловим необходимое:

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

А также стоит наверное все же разъяснить это
В обоих вариантах индекс будет использоваться, поскольку поле "Документ" находится в начале индекса.
По ряду причин был выбран второй вариант и после индексации измерения документ, дедлоки больше не возникали.

Что ряд причин это ни что иное как уже существующий код в других местах конфигурации, который использует индекс именно в этой последовательности
Номенклатура + ЕдиницаИзмерения + Документ + Период (Fld8073 + Fld8074 + Fld8075 + Period)

И если сдвинуть измерение "Документ" выше других то индекс перестроится к виду:
Документ + Номенклатура + ЕдиницаИзмерения + Период (Fld8075 + Fld8073 + Fld8074 + Period)

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

А так за статью конечно плюс!
15. Fox-trot 125 09.07.19 07:30 Сейчас в теме
(0) проще грохнуть этот сомнительный регистр, код кривой, индексы кривые... шутка
16. Dach 304 09.07.19 09:22 Сейчас в теме
"Итак, получается первым запросом у нас блокируется одна запись из регистра _InfoRg8072, а потом блокируется почти весь регистр (рамках разделителя) до окончания транзакции."

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

Плюсую за отдельный индекс по измерению "Документ".

А еще можно чуть изменить прикладную логику. Вторую процедуру (судя по ее названию) - вполне можно вынести в регламентное задание. Регистрировать где-нибудь проводимые документы (в плане обмена, отдельном регистре и т.д.) и затем обрабатывать.
18. azazana 63 09.07.19 09:56 Сейчас в теме
Как Вам уже верно заметили - блокируется действительно только одна запись, а затем идет частичный скан таблицы, потому что индексы использовать не удалось и среди сканируемой области как раз и попадается точно также заблокированная запись - вот и дедлок.

Спасибо, видимо я не внятно написала, раз для остальных это неочевидно. Если вы не против, я добавлю это в свой текст.
17. capitan 1908 09.07.19 09:51 Сейчас в теме
Мне одному кажется что не обязательно делать запись в цикле ?
И нафига его вообще читать если все равно потом перезаписывать.
Или это учебный пример ?
Ну а то что дедлок с индексами никак не связан - это уже выше сказали, дедлок - это повышение уровня транзакции, его вы не поймали.
triviumfan; +1 Ответить
19. azazana 63 09.07.19 10:06 Сейчас в теме
(17) У меня не стояла задача критиковать код коллеги, честно говоря, у меня тоже много к нему вопросов)
Это реальный пример из рабочей базы.
А дедлок с индексами связан, выше я объяснила почему.
Это дедлок не повышения уровня транзакции, у вас, видимо, путаница в терминологии, вы имели ввиду повышение режима блокировки, но это все равно не он)
Это дедлок захвата ресурса в разном порядке. Еще раз попробую объяснить:
Первый пользователь захватывает ресурс 1 в регистре сведений,
Второй пользователь захватывает ресурс 2 в регистре сведений,
Дальше первый пытается захватить весь регистр (поскольку в плане запроса скан), но не может - натыкается на захват ресурса 2.
Второй так же пытается захватить весь регистр, но не может, поскольку натыкается на захват ресурса 1.
Итого - дедлок. Пожалуй, добавлю это объяснение в текст
20. capitan 1908 09.07.19 10:49 Сейчас в теме
(19)
Повышение уровня блокировки ресурса в рамках одной транзакции если уже быть до конца точным
В методических примерах на расследование взаимоблокировок точно такой же код
Посмотрите на ИТС
Индексы тут не при чем
то что индекс сканируется это плохо, но отсюда не следует что он в конфликте блокировок
С каких интересно пирогов сканирование индекса начало захват ресурса на взаимоблокировку делать ?
Это было бы блокировкой, второй кто ожидает отвалился бы таймауту
А вы как раз читаете и пишете набор записей в цикле - это классический пример взаимоблокировки с повышением уровня
только там в отладчике ставится точка останова, а вам коллега подогнал такой вот пример
И причину дедлока вы не поймали, а поймали его хвост - его было видно и в сообщении ошибки 1С, можно было с КИП и профайлером не заморачиваться
21. azazana 63 09.07.19 11:22 Сейчас в теме
(20) Я не исключаю, что вы правы, и действительно, там есть еще один дедлок, но пользователями он не ловится. Когда у меня будет время я проверю это. Но в статье обсуждается не этот дедлок.
Давайте пойдем по другому.
По тексту видно, что дедлок возник на блокировках СУБД.
Когда читается набор записей регистра, какая блокировка накладывается? Управляемая S.
Когда записывается набор записей регистра, какая блокировка накладывается? Управляемая X.
Получаем дедлок на управляемых блокировках, а у здесь дедлок на СУБД.
С каких интересно пирогов сканирование индекса начало захват ресурса на взаимоблокировку делать ?

Вы же не будете спорить, что сканирование индекса приводит к избыточным блокировкам? Избыточные блокировки часто являются причиной дедлока.
22. capitan 1908 09.07.19 11:32 Сейчас в теме
(21)Сканирование индекса просто увеличивает время транзакции и тем что вы добавили индекс вы это время просто сократили и теперь у вас перестали во времени пересекаться люди записывающие документы.
Как только они пересекутся во времени - вы тут же поймаете точно такой же дедлдок.
Проверит можете элементарно на двух рабочих местах проведя документы одновременно.
А при хорошем коде (привет вашему коллеге) дедлок вы не поймаете, второй пользователь просто встанет в ожидание на блокировке и дождется его если только у вас документ 20 сек не будет проводиться.
Отсюда некоторая мораль - вы не обсуждаете код ваших коллег, а берете костылик в виде добавочного индекса и подпираете им код кривенький код ваших коллег.
Т.е. базе вашей и так нехорошо живется, а вы ей еще один индекс подбросили.
А на регистре сведений и не один наверняка.
А почему бы вашему коллеге не взять все поля в отбор - он же по номенклатуре пишет сведения ?
Вспоминается...
Трубоукладчики — очень вежливые люди и всегда пропускают асфальтоукладчиков вперёд.
У вас с вашим коллегой точно такая же история.
Вместо того чтобы сказать - Вася поправь свой код, на что ушло бы 5 мин, вы тоже произвели немаленькие работы с КИП даже и в результате количество косяков в вашей базе увеличилось.
24. buganov 156 09.07.19 11:49 Сейчас в теме
(22) на самом деле, есть в ее словах доля истины. Здесь пример, прямо, как из методички
https://infostart.ru/public/708360/
25. capitan 1908 09.07.19 11:57 Сейчас в теме
(24)Попытка увеличения уровня блокировки ресурса в последующих операциях (например - чтение и последующая запись)
Последовательность действий, приводящая к взаимной блокировке:

Транзакция Т1 выполняет запрос к таблице остатков регистра Р1 и устанавливает разделяемую блокировку на прочитанные записи.
Транзакция Т2 выполняет запрос к таблице остатков регистра Р1 и устанавливает разделяемую блокировку на прочитанные записи. Поскольку разделяемые блокировки совместимы, то ей удается это сделать.
Транзакция Т1 записывает движения документа и пытается обновить записи в таблице остатков регистра Р1. Для этого требуется установить на эти записи эксклюзивную блокировку. Ей это не удается потому, что на эти записи наложена транзакцией Т2 разделяемая блокировка , не совместимая с эксклюзивной. Транзакция Т1 приходится ждать, когда транзакция Т2 закончится и снимет установленную блокировку.
Транзакция Т2 записывает движения документа и пытается обновить записи в таблице остатков регистра Р1. Для этого требуется установить на эти записи эксклюзивную блокировку. Ей это не удается потому, что на эти записи наложена транзакцией Т1 разделяемая блокировка , не совместимая с эксклюзивной. Транзакция Т2 приходится ждать, когда транзакция Т1 закончится и снимет установленную блокировку.
Можно заметить, что этот процесс никогда бы не закончился, если бы одна из транзакций не была отменена Microsoft SQL Server принудительно.

Избежать подобной ситуации можно, используя при выполнении запроса к таблице остатков регистра Р1 оператор "ДЛЯ ИЗМЕНЕНИЯ". В этом случае на прочитанные записи будет установлена блокировка более высокого уровня - блокировка обновления. Такая блокировка совместима с разделяемой, что позволит транзакциям, осуществляющим чтение данных, на которые установлена блокировка обновления, обращаться к этим данным беспрепятственно. А когда понадобится их обновить, то проблем быть не должно, так как блокировки обновления между собой несовместимы, и, значит, другие транзакции, читающие эти данные для последующего изменения (и естественно тоже запросившие их с блокировкой обновления), будут ждать, пока эти данные поменяются, не препятствуя другим сессиям.
https://its.1c.eu/db/metod8dev/content/2309/hdoc/_top/deadlock
37. buganov 156 10.07.19 05:57 Сейчас в теме
(25) Конструкция "ДЛЯ ИЗМЕНЕНИЯ" будет проигнорирована в управляемом режиме блокировок
26. azazana 63 09.07.19 11:59 Сейчас в теме
(22) Мой коллега уволился 5 дней назад (С)
Сканирование индекса просто увеличивает время транзакции и тем что вы добавили индекс вы это время просто сократили и теперь у вас перестали во времени пересекаться люди записывающие документы.

Вы не правы.
Вот цитата с сайта http://www.gilev.ru/index/
ВЛИЯНИЕ ИНДЕКСОВ НА БЛОКИРОВКИ
Отсутствие необходимого индекса для запроса означает перебор всех записей таблицы, что в свою очередь приводит к избыточным блокировкам, т.е. блокируются лишние записи. Кроме того, чем дольше выполняется запрос из-за отсутствующих индексов, тем больше время удержания блокировок.

Это достаточно авторитетный источник?
Вот еще цитата с ИТС:
Если в структуре базы данных отсутствует индекс, удовлетворяющий всем перечисленным условиям, то для получения результата СУБД будет вынуждена сканировать таблицу или один из ее индексов. Это приведет к увеличению времени выполнения запроса, а также к возможному снижению параллельности системы, поскольку возрастет количество установленных блокировок. [IS-QUOTE]
https://its.1c.ru/db/v8std#content:652:hdoc:_top:%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B%20%D0%B8%20%D0%B1­%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8
[IS-QUOTE]Проверит можете элементарно на двух рабочих местах проведя документы одновременно.

Воспроизвести ваш пример дедлока не получится.
Я не могу одновременно с двух рабочих мест провести один и тот же документ. (отбор же стоит по документу). Именно поэтому он и не возникает в рабочей базе.
29. capitan 1908 09.07.19 12:20 Сейчас в теме
(26)Вы путаете блокировки и взаимоблокировки.
блокировки ждут окончания, а взаимоблокировки сразу рубятся сервером.
Поэтому при сканировании таблиц в общем случае просто все будет медленно работать.
А так как у вас написан код - он будет крашиться

И проводить не обязательно не один и тот же документ
32. azazana 63 09.07.19 12:29 Сейчас в теме
(29) Если я проведу другой документ, то откуда взятся дедлоку? Читаются разные записи, записываются тоже.
В вашем примере с ИТС читаются, а потом записываются одни и те же записи у первой и второй транзакции.
50. CSiER 30 10.07.19 18:07 Сейчас в теме
(21)
Когда читается набор записей регистра, какая блокировка накладывается? Управляемая S.

Как в snapshot может появиться s-блокировка?

Без snapshot сканирование индекса с S-блокировкой (или неоптимальный план => эскалация) - согласен.
72. azazana 63 11.07.19 18:23 Сейчас в теме
(50) Я говорила по управляемые блокировки. Они к RCSI не имеют отношение.
73. CSiER 30 12.07.19 04:57 Сейчас в теме
(72) теперь понятно, спасибо.
23. buganov 156 09.07.19 11:47 Сейчас в теме
(19) Задумался, откуда у Вас U блокировка и наткнулся на интересную статью, которая в полной мере объясняет Вашу ситуацию.

В одной сессии мы установили монопольную блокировку (X) на одну(или диапазон) из строк таблицы. В другой сессии мы пытаемся обновить другую строку(или диапазон) этой же таблицы и запускаем запрос на обновление с неоптимальным планом, что приводит к сканированию всей таблицы. SQL Server будет устанавливать блокировку обновления (U) на каждую просканированную строку, но в итоге не сможет завершить операцию, т.к. попытается прочитать строку, на которой уже была установлена монопольная блокировка (X). И при этом неважно, что мы хотим обновить совершенно другую строку, для SQL Server необходимо прочитать строку, чтобы установить на нее блокировку обновления (U), и после этого проверить, нужно ли ее обновить.

Можете спросить у автора разрешение внести выдержки в свою статью.
https://infostart.ru/public/708360/

В Вашем примере, конечно, напрашивается индекс по полю документ, в случае использования текущей архитектуры регистра в других местах, например, отчетах. Если нет, то можно и перенести наверх. А можно было бы и переписать логику удаления признака ошибки
27. azazana 63 09.07.19 12:15 Сейчас в теме
(23) Да, U блокировка возникает именно оттуда. Дальше в транзакции происходит удаление данных.
DELETE FROM T1
FROM dbo._InfoRg8072 T1
WHERE (T1._Fld8075_TYPE = 0x08 AND T1._Fld8075_RTRef = 0x000000B6 AND T1._Fld8075_RRRef = ?) AND (T1._Fld385 = ?)
Кстати, тоже со сканированием. Возможно, что если бы я использовала этот запрос вопросов было бы меньше, зато так интереснее))
38. nytlenc 10.07.19 07:01 Сейчас в теме
(17)
Мне одному кажется что не обязательно делать запись в цикле?
И нафига его вообще читать если все равно потом перезаписывать.

Одному :)

Вы явно невнимательный человек или вовсе не программист 1С.
Еще раз посмотрите внимательно на код :) И подумайте
Во первых набор записей читается чтобы проверить условие, есть-ли вообще что-то в регистре сведений по этому измерению "Документ"?
Во вторых набор записей читается для того, чтобы изменить там всего один реквизит и если вы его запишите без чтения то тупо затрете все данные в регистре которые там были...
Далее проверка условия - Если есть какие-то записи по документу в регистре тогда все записи набора перебираются в цикле и им устанавливается значение реквизита "Ошибка" в ЛОЖЬ.
После чего уже когда цикл завершился производится целиком запись всего набора а не запись в цикле как вы написали.

НаборЗаписей = РегистрыСведений.ИзмененияЕдиницИзмеренийНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Документ.Установить(Документ);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество()>0 Тогда
     Для Каждого Запись из НаборЗапией Цикл
          Запись.Ошибка = Ложь;
     КонецЦикла;
     НаборЗаписей.Записать();
КонецЕсли;
Показать
48. capitan 1908 10.07.19 16:11 Сейчас в теме
(38)Поскольку по нику фиг поймешь дама вы или нет, то на всякий случай отвечу вежливо.
Во первых нафига читать набор записей регистра если все равно его записывать потом при любом раскладе, что вы там затрете Запись.Ошибка = Ложь? А нельзя это тоже записать ?
Во вторых нафига делать это в цикле ? Набор записей он на то и набор чтобы его один раз можно было записать
В третьих так и не понятно эта вся канитель в транзации проведения что ли происходит ? Это будет вообще крындеТц
В четвертых - кто запрещает при проведении использовать те же отборы что и при записи ? Религия ?
И откуда взялась мысль про захват ресурсов в разном порядке ? В каком нафиг разном порядке если во втором запросе ресурс один - документ ?
Короче вы дамы что то мутите, но логику я постичь пока не могу вашего кода.
То ли я невнимательный, то ли не программист 1С )
life-wayfarer; +1 2 Ответить
49. nytlenc 10.07.19 18:04 Сейчас в теме
(48)
во первых нафига читать набор записей регистра

я уж не знаю что там хотел и имел в виду программист который писал код, но я комментирую то что есть,
Лично для Вас повторяю во второй раз, судя из кода - чтобы проверить условие
Если НаборЗаписей.Количество()>0 Тогда

именно для этого и читается набор записей.
если все равно его записывать

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

Вы опять за свое? Глаза переведите выше через один пост в (38) и посмотрите еще раз внимательно в код. Где вы там узрели запись вы цикле????!!! о_О Запись вынесена за пределы цикла!
В четвертых - кто запрещает при проведении использовать те же отборы что и при записи ? Религия ?

В четвертых где вы увидели в комментируемом мной куске кода изменение отборов? Используются одни и те же. А точнее один "Документ"
И откуда взялась мысль про захват ресурсов в разном порядке ? В каком нафиг разном порядке если во втором запросе ресурс один - документ ?

тут на самом деле вопрос не ко мне видимо, потому что про захват ресурсов я ничего не говорил
То ли я невнимательный, то ли не программист 1С )

Уж не внимательный это 100%
77. life-wayfarer 18.11.19 00:04 Сейчас в теме
(48)
Короче вы дамы что то мутите, но логику я постичь пока не могу вашего кода.


Что вы понимали за что вам ставят минусы:)

Процедура ПриЗаписи(Отказ)
	ДвиженияДокументовПоРегистру(Ссылка);
КонецПроцедуры

Процедура ДвиженияДокументовПоРегистру(Документ) Экспорт
		 
	НаборЗаписей = РегистрыСведений.ИзмененияЕдиницИзмеренияНоменклатуры.СоздатьНаборЗаписей();
	Для каждого Строка из Документ.Товары Цикл
		НаборЗаписей.Отбор.Документ.Установить(Документ.Ссылка);
		НаборЗаписей.Отбор.Номенклатура.Установить(Строка.Номенклатура);
		НаборЗаписей.Отбор.ЕдиницаИзмерения.Установить(Строка.ЕдиницаИзмерения);
		Если НаборЗаписей.Количество()>0 Тогда
			Для Каждого Запись из НаборЗаписей Цикл
				Запись.ЕдиницаИзмерения = Строка.ЕдиницаИзмерения;
				Запись.Номенклатура = Строка.Номенклатура;			
			КонецЦикла;
		Иначе
			Запись = НаборЗаписей.Добавить();
			Запись.Документ = Документ.Ссылка;
			Запись.ЕдиницаИзмерения = Строка.ЕдиницаИзмерения;
			Запись.Номенклатура = Строка.Номенклатура;
			Запись.Ошибка = Ложь;
			Запись.Период = ТекущаяДата();
		КонецЕсли;
		НаборЗаписей.Записать(Истина);		
	КонецЦикла;
КонецПроцедуры

Процедура УдалитьПризнакНаличияОшибкиПриПроведенииДокументов(Документ) Экспорт
	
	НаборЗаписей = РегистрыСведений.ИзмененияЕдиницИзмеренияНоменклатуры.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.Документ.Установить(Документ);
	НаборЗаписей.Прочитать(); 
	Если НаборЗаписей.Количество()>0 Тогда
		Для Каждого Запись из НаборЗаписей Цикл
			Запись.Ошибка = Ложь;			
		КонецЦикла;
		НаборЗаписей.Записать(Истина);
	КонецЕсли; 
	
КонецПроцедуры

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
	УдалитьПризнакНаличияОшибкиПриПроведенииДокументов(Ссылка);
КонецПроцедуры

Показать
78. capitan 1908 18.11.19 09:52 Сейчас в теме
(77)Я знал что будет плохо, но не знал что так скоро. ©
Вы пишете - читаете и снова пишете в периодический регистр при проведении документа.
Причем с разными отборами.
Это толково. Так конечно никаких блокировок никогда не случится. Они все от смеха поумирают.
79. life-wayfarer 18.11.19 12:10 Сейчас в теме
(78)
77)Я знал что будет плохо, но не знал что так скоро. ©
Вы пишете - читаете и снова пишете в периодический регистр при проведении документа.
Причем с разными отборами.
Это толково. Так конечно никаких блокировок никогда не случится. Они все от смеха поумирают.


Это был сарказм. Код из базы которую выложил автор и никакого отношения к нему не имею. По моему скромному мнению очень показательный пример.
28. capitan 1908 09.07.19 12:16 Сейчас в теме
Все. Вспомнил где я видел это

&НаКлиенте
Процедура ПервыйУчастник(Команда)   ПервыйУчастникНаСервере(); 

КонецПроцедуры
    &НаСервереБезКонтекста
Процедура ПервыйУчастникНаСервере()    НачатьТранзакцию();
    НаборЗаписейРегистрСведений1 = РегистрыСведений.РегистрСведений1.СоздатьНаборЗаписей();
    НаборЗаписейРегистрСведений1.Отбор.Измерение1.Установить("Test1");
    НаборЗаписейРегистрСведений1.Отбор.Измерение2.Установить("Test2");
    //TLOCK shared
    НаборЗаписейРегистрСведений1.Прочитать();
        //5 секунд паузы
    СделатьПаузу(5000);
        //TLOCK exclusive
    НаборЗаписейРегистрСведений1.Записать();
             ЗафиксироватьТранзакцию();
КонецПроцедуры
     &НаКлиенте

 Процедура ВторойУчастник(Команда)    ВторойУчастникНаСервере();

 КонецПроцедуры
      &НаСервереБезКонтекста Процедура ВторойУчастникНаСервере()    НачатьТранзакцию();
     НаборЗаписейРегистрСведений1 = РегистрыСведений.РегистрСведений1.СоздатьНаборЗаписей();
     НаборЗаписейРегистрСведений1.Отбор.Измерение1.Установить("Test1");
     НаборЗаписейРегистрСведений1.Отбор.Измерение2.Установить("Test2");
     //TLOCK shared
     НаборЗаписейРегистрСведений1.Прочитать();
         //5 секунд паузы
     СделатьПаузу(5000);
       //TLOCK exclusive
     НаборЗаписейРегистрСведений1.Записать();
              ЗафиксироватьТранзакцию();
 
  КонецПроцедуры
Показать


Не напоминает код вашего коллеги? Только вместо паузы у него цикл по таблице документа )
А это как раз пример с ИТС про ошибку взаимоблокировки на управляемых блокировках
30. azazana 63 09.07.19 12:22 Сейчас в теме
(28) Напоминает) Только есть одна проблема. В коде отбор ставится по документу. Который в данный момент проводится.
И второй пользователь не может провести такой же документ (с такой же ссылкой). Больше этот код (кроме как при проведении) не используется.
Хорошо, только ради вас, я воспроизведу дедлок СУБД, установив управляемую блокировку перед чтением регистра. Это будет достаточным доказательством?
31. capitan 1908 09.07.19 12:29 Сейчас в теме
(30)Лестное предложение )
Только область блокировки задайте правильно - по номенклатуре из табличной части
и на мой взгляд - вуаля - взаимоблокировку вы не словите
33. azazana 63 09.07.19 15:41 Сейчас в теме
(31) Добавила воспроизведение дедлока в статью после установки управляемой блокировки.
35. capitan 1908 09.07.19 17:53 Сейчас в теме
(33)Было бы не кисло еще и транзакцию начать )

Ничего что я на ИТС ссылаюсь а не на сайты в интернете?

Неправильно:

// 1. Прочитать регистр сведений
Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
|ИЗ
| РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
|ГДЕ
| ЗаметкиПоПредмету.Предмет = &Предмет");
Запрос.УстановитьПараметр("Предмет", ПредметЗаметок);
Выборка = Запрос.Выполнить().Выбрать();

КоличествоЗаметок = 0;
Если Выборка.Следующий() Тогда
КоличествоЗаметок = Выборка.КоличествоЗаметок;
КонецЕсли;

// 2. Записать в регистр сведений
НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Предмет = ПредметЗаметок;
НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
НаборЗаписей.Записать();

Правильно:

// 1. Начать транзакцию для пакета из двух операций чтения и записи регистра
НачатьТранзакцию();

Попытка
// 2. Установить исключительную блокировку на интересующий диапазон записей регистра,
// для того чтобы гарантировать, что в момент записи количество заметок не изменилось с момента чтения в каком-либо другом сеансе.
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("РегистрСведений.ЗаметкиПоПредмету");
ЭлементБлокировкиДанных.УстановитьЗначение("Предмет", ПредметЗаметок);
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();

// 3. Прочитать регистр сведений
Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
|ИЗ
| РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
|ГДЕ
| ЗаметкиПоПредмету.Предмет = &Предмет");
Запрос.УстановитьПараметр("Предмет", ПредметЗаметок);

Выборка = Запрос.Выполнить().Выбрать();

КоличествоЗаметок = 0;
Если Выборка.Следующий() Тогда
КоличествоЗаметок = Выборка.КоличествоЗаметок;
КонецЕсли;

// 4. Записать в регистр сведений
НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Предмет = ПредметЗаметок;
НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
НаборЗаписей.Записать();

ЗафиксироватьТранзакцию();
Исключение
// 5. Если при установке блокировки возникла исключительная ситуация из-за того, что регистр уже заблокирован в другом сеансе (или по другим причинам),
// отменить транзакцию и записать сведения об ошибке в журнал регистрации.
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации(НСтр("ru = 'Заметки'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
Показать
36. azazana 63 09.07.19 22:20 Сейчас в теме
(35) Явно начинать транзакцию абсолютно необязательно в данном случае. Повторю, идет запись и проведение документа. А значит транзакция уже начата.
И да, я тоже ссылаюсь на ИТС, а не на сайты в интернете.
Вот еще раз дублирую:
Если в структуре базы данных отсутствует индекс, удовлетворяющий всем перечисленным условиям, то для получения результата СУБД будет вынуждена сканировать таблицу или один из ее индексов. Это приведет к увеличению времени выполнения запроса, а также к возможному снижению параллельности системы, поскольку возрастет количество установленных блокировок.

https://its.1c.ru/db/v8std#content:652:hdoc
40. capitan 1908 10.07.19 09:28 Сейчас в теме
(36)А вы попробуйте. Как говорил товарищ Берия: Попытка не пытка.
И по вашему любая функция из модуля документа выполняется в транзации ?
51. CSiER 30 10.07.19 18:08 Сейчас в теме
(40) а лучше демо-пример, чтобы мы сами могли попробовать:)
56. azazana 63 10.07.19 21:41 Сейчас в теме
(40)
Еще раз: я выложила эту статью не для того, чтобы обсудить чей-то код, а для того чтобы обсудить способ поимки дедлока.
Те "способы" его поимки, которые вы предлагаете - это тыканье палочкой в код с надеждой, что на этот раз тычок что-то даст. Но чтобы найти дедлок нужно использовать не метод тыка, а специальные инструменты, такие как ЦУП, ТЖ и пофайлер.
Но в целом, все ваши предложения вы теперь можете попробовать на практике. Если получится избежать дедлока с помощью управляемой блокировки с сохранением параллельности работы и без изменения логики программы - мое увОжение.
63. CSiER 30 11.07.19 08:51 Сейчас в теме
(56)
Процедура УдалитьПризнакНаличияОшибкиПриПроведенииДокументов(Документ) Экспорт
	// Вариант без изменения индексов придётся блокировать весь РС {
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ИзмененияЕдиницИзмеренияНоменклатуры");
	ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
	Блокировка.Заблокировать();
	// }
...
Показать

В данном случае транзакции будут проходить последовательно.
67. azazana 63 11.07.19 13:24 Сейчас в теме
(63) Мощно)))
Только параллельности работы не будет.
70. CSiER 30 11.07.19 16:45 Сейчас в теме
(67) Да, будет последовательное выполнение. Думаю, что решить проблему через. упр. блокировки по другому в данном случае не получится - область блокировки должна быть не меньше области изменяемых данных (а у нас частичный скан индекса).
34. triviumfan 24 09.07.19 16:04 Сейчас в теме
Не понял, так запись в регистр идёт как при записи документа, так и при его проведении?
ЗЫ: ДвиженияДокументовПоРегистру(Документ) нужно переписать, там наблюдаются признаки параноидной шизофрении.
capitan; azazana; +2 Ответить
39. nytlenc 10.07.19 07:15 Сейчас в теме
(34) не совсем понимаю где вы там усмотрели признаки шизофрении, по моему там все в порядке учитывая, что регистр наверняка не подчинен регистратору и не периодический (лишь в этом случае можно считать этот код бредом), в противном случае писать в регистр нужно набором записей, учитывая еще то, что при этом нужно проверить некоторые условия (см. код процедуры) то вполне оправдано проверять их после чтения набора записей.
А как вы бы оптимизировали этот "параноидально шизофреничный" по вашему мнению код?
41. triviumfan 24 10.07.19 09:33 Сейчас в теме
(39)
1. Запись набора записей в цикле можно легко переделать
2. В чем смысл устанавливать отбор по измерениям "Номенклатура" и "ЕдиницаИзмерения", если потом идёт перезаполнение ПРЕДЫДУЩЕГО НАБОРА (ведь чтения нет)? И как можно это расценивать, если запись произойдёт все-равно с теми измерениями, что установлены в отборе данными ПО ТЕКУЩЕЙ СТРОКЕ ТЧ, соответственно это что не на есть признаки ШИЗОФРЕНИИ. ТАК ПОНЯТНО?!
ЗЫ: и это пишет программист с 10+ летним стажем?!
Fox-trot; +1 Ответить
43. Fox-trot 125 10.07.19 10:20 Сейчас в теме
44. nytlenc 10.07.19 10:49 Сейчас в теме
(41) ахахах ))) сейчас перечитал процедурку, и увидел что во первых реально чтения там вообще нет (и условие Количество()>0 никогда не сработает), а также запись действительно в цикле что увеличивает нагрузку на порядок... Бред. Согласен шизофрения программиста на лицо.
47. triviumfan 24 10.07.19 14:59 Сейчас в теме
(44) Почему же не сработает? Ещё как сработает. Просто это бессмысленно.
Условие выполнится на следующей итерации, т.е. со второй строки ТЧ.
И даже если бы было сначала чтение - все равно логики тут нет:)
42. capitan 1908 10.07.19 09:52 Сейчас в теме
(39)
Вспоминается...
Я презрение глаголы. Злость на людей, которые их похвала

Да там полностью кривой код в принципе.
Плюсом к этому идет "улучшение" от автора публикации в виде индекса по документу, который там нафиг не нужен.
Просто топик стартер дама и это не позволяет мне в полной мере выразить восхищение, а коллега вот не постеснялся
Fox-trot; triviumfan; +2 Ответить
58. azazana 63 10.07.19 22:24 Сейчас в теме
(42) (43) В книге "Настольная книга эксперта по технологическим вопросам" написано, что не стоит бросаться оптимизировать код, который не вызывает проблем и это как раз такой случай, вы потратите время, а дедлок все равно будет воспроизводиться.
Можете это проверить на модельной базе.
52. fedorovd81 10.07.19 18:13 Сейчас в теме
Автор правильно заметила, что здесь возникает дедлок из-за захвата ресурсов в разном порядке. Решение в принципе неплохое. На мой взгляд для решения этой проблемы, необходимо обеспечить одинаковый захват ресурсов в обеих процедурах. Т.е. или при записи отключить отборы по номенклатуре и ЕИ, или при проведении добавить отборы по номенклатуре и ЕИ. На мой взгляд первый вариант предпочтительнее, т.к. убирает ещё и запросы в цикле и делает однократную запись в РС. С учётом того, что добавлен индекс по документу, процедура после доработки должна работать быстрее.
60. azazana 63 10.07.19 23:02 Сейчас в теме
(52) Предполагаю, что вы правы, я до конца не разобрала тот бизнес-процесс в рабочей базе, где используется этот код. Но чисто теоретически я могу придумать ситуацию, где отборы должны стоять именно таким образом.
В любом случае, это интересный модельный пример.
54. PerlAmutor 124 10.07.19 20:03 Сейчас в теме
В целом круто. У меня в организации вообще нет ни одного человека, кроме меня, кто бы залез хотя бы настолько глубоко в 1С. Сама тема непростая, в ней необходимо хорошо разбираться, чтобы представить себе полную цепочку событий со своими нюансами.
57. azazana 63 10.07.19 21:42 Сейчас в теме
Дорогие коллеги. Я подготовила для вас модельную базу, на которой воспроизводится дедлок. Там используется точно такой же код, который представлен в статье, специально, чтобы вы могли поупражнятся в оптимизации кода и установить какие угодно транзакции и блокировки.
PS
1. не забудьте развернуть базу в клиент-серверном варианте.
2. Дедлок возникает, если поставить точку останова в строке 40 модуля объекта заказа поставщику.
59. fedorovd81 10.07.19 22:48 Сейчас в теме
(57) Мне лень упражняться :). Вот совет по оптимизации могу дать!
65. triviumfan 24 11.07.19 12:28 Сейчас в теме
(57) А можно прямо в комментарии ссылку на файлообменник?)
66. azazana 63 11.07.19 13:22 Сейчас в теме
74. Dach 304 12.07.19 13:47 Сейчас в теме
Отчасти согласен с предыдущими ораторами о том, что вместо индексов новых неплохо бы схему работы изменить и весь код переписать...
Про РЗ и постобработку уже говорил, а еще можно сделать в этой ситуации также, как 1С сделала с таблицами итогов - добавить в проблемную таблицу измерение-сплиттер, правда и тут придется периодически сворачивать записи, да и все запросы переписать.

Реалии жизни, к сожалению, как правило другие. Заказчик со слезами на глазах просит "ну хоть как-то починить за вменяемое время-деньги". А ты, глядя на все это, понимаешь, что переписав кусочек тут - придется переписать и там, а потом еще и вот там и вот еще и там ну и т.д. и в итоге надо Ctrl+A, Del, написать все заново ))) А тут худо-бедно проблема решена, и спец, который может ее решить без лишнего нытья - молодец
75. azazana 63 13.07.19 01:25 Сейчас в теме
(74)
Отчасти согласен с предыдущими ораторами о том, что вместо индексов новых неплохо бы схему работы изменить и весь код переписать...

Я и сама с ними согласна. Только того, кто это написал уже нет в компании, а времени на погружение и переписывание мне никто не даст. И других задач полно.
76. Fox-trot 125 13.07.19 06:29 Сейчас в теме
(75)
времени на погружение и переписывание мне никто не даст
проще тогда в цикле добавить каждому полю по индексу - сэкономите кучи времени себе и остальным программистам
и ваша база заиграет новыми ... :-)
Оставьте свое сообщение

См. также

Еще один тест 1C: Postgres SQL 11 Pro Enterpise против MSSQL 14 под Windows 2012 Server R2 Промо

Производительность и оптимизация (HighLoad) v8 Абонемент ($m)

Проработав 15 лет с MSSQL в 2017 начал активно СУБД Postgres SQL. За два года успел поработать в 9 версии Postgres и в 10-ой. И пришел к выводу, что существуют реальное замедление работы баз после перехода на Postgres. Недавно вышла 11 версия Postgres Pro Enterpise, которая обещает почти 2-х кратное ускорение над 11 Pro Standart и 10-ой версией. Закупив лицензию Postgres 11 Pro Enterpise Это я и решил проверить на 1С.

1 стартмани

05.09.2019    16450    Indgo    107    

Как сдать экзамен 1С:Специалист по платформе?

Решение задач на 1С:Специалист v8 Россия Абонемент ($m)

Не пора ли получить сертификат 1С:Специалист по платформе? Для этого ...

1 стартмани

18.01.2021    9192    vasilievil    9    

Водопад из Техжурнала 1С

Производительность и оптимизация (HighLoad) v8 1cv8.cf Абонемент ($m)

Строим визуализацию в виде waterfall-графика по данным событий технологического журнала.

5 стартмани

23.12.2020    4636    VKislitsin    5    

Cбор и анализ ошибок при помощи Sentry, или как упростить жизнь себе и пользователям

Практика программирования Интеграция v8 Абонемент ($m)

Цель данной статьи - сделать процесс сбора и анализа ошибок, происходящих в базе, максимально простым, быстрым и удобным, собирать статистику по ошибкам, местам их возникновения и частоте их появления, а также в деталях разобрать все тонкости по интеграции 1С с Sentry.

1 стартмани

09.10.2020    3947    hexhoc    12    

Безопасная работа с транзакциями во встроенном языке Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Разбираемся с опасностями использования транзакций во встроенном языке 1С. Познаем ошибку "В данной транзакции уже происходили ошибки". Учимся защищаться от них.

1 стартмани

25.03.2019    38398    tormozit    54    

Программная корректировка при выводе отчета СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

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

1 стартмани

08.10.2020    5281    dabu-dabu    10    

Библиотека программного изменения формы (УФ)

Инструментарий разработчика Работа с интерфейсом Универсальные функции v8 1cv8.cf Абонемент ($m)

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

1 стартмани

07.08.2020    5113    BuriyLesha    17    

Работа с хранилищем конфигурации из режима 1С: Предприятие минуя конфигуратор

Хранилище v8 1cv8.cf Абонемент ($m)

Описание приемов работы с хранилищем конфигурации 1С из режима 1С: Предприятие минуя конфигуратор. Статья содержит ряд примеров работы с хранилищем по протоколу HTTP, описание "внутренностей", а также демонстрационную обработку

3 стартмани

11.06.2020    6694    MaxxG    19    

План подготовки к аттестации на 1С: Специалиста по платформе (+ Ссылки на материалы) Промо

Решение задач на 1С:Специалист v8 Россия Абонемент ($m)

Хочу поделиться собственным планом подготовки к аттестации на 1С: Специалист по платформе 8.3 со ссылками на материалы (и указанием стоимости).

1 стартмани

23.12.2017    23984    tmn72.1C    39    

История данных и БСП

БСП (Библиотека стандартных подсистем) v8 1cv8.cf Абонемент ($m)

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

1 стартмани

09.06.2020    4229    zeegin    17    

Telegram bot API - разбор документации с примерами

WEB v8 Абонемент ($m)

Перевод документации на язык 1С.

1 стартмани

06.04.2020    49868    leongl    59    

Как выполнить отчет на СКД через COM и получить данные отчета? Промо

Практика программирования v8 УПП1 Россия Абонемент ($m)

Для чего это нужно. Например, нужно в одной базе получить какой-либо показатель из другой базы. Этот показатель вычисляется в каком-либо сложном отчете, который написан на СКД. Можно, конечно, "скопипастить" текст запроса из другой базы, немного подправить его и выполнять в том же COM подключении. Но с этим теряется гибкость: если отчет изменился, то нужно помнить о том, что где-то есть его "немного модифицированная" копия. В статье будет рассмотрен пример получения данных из базы ЗУП.

2 стартмани

08.05.2018    27610    wowik    3    

Методика обновления формы объекта данных при изменении объекта

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

В формах объектов данных часто встречаются элементы, косвенно связанные с объектом. Логику обновления этих элементов при изменении объекта обычно вызывают из обработчиков ПриСозданнииНаСервере и ПриОткрытии, забывая про наличие других способов изменения объекта. В статье предложена методика для обычных и управляемых форм, учитывающая все способы.

1 стартмани

09.03.2020    11445    tormozit    14    

Отправка уведомлений с помощью командной строки, Оповещения с сервера на клиент с помощью командной строки

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

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

1 стартмани

05.03.2020    6512    user5300    3    

Конвертация данных 2. Использование исходящих и входящих данных. Свойство "Получить из входящих данных"

Обмен данными 1С Перенос данных из 1C8 в 1C8 v8 КД Абонемент ($m)

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

17.02.2020    19304    Drivingblind    31    

Как нарисовать граф на 1С Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

09.08.2013    71431    ildarovich    117    

Вывод сообщений в HTML поле средствами 1С

Практика программирования v8 v8::УФ Абонемент ($m)

Пример использования вывода большого количества сообщений в поле HTML. С возможностью открывать ссылочные объекты и создавать новые объекты передавая параметры прямо из HTML поля. Протестировано на релизах 8.3.12 и 8.3.15+

2 стартмани

31.01.2020    6590    burni4    16    

Краткое руководство по внесению изменений в конфигурацию

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

13.01.2020    19248    sapervodichka    41    

Тест серверного оборудования на допустимое количество пользователей: как это использовать?

Администрирование СУБД Нагрузочное тестирование Сервера v8 1cv8.cf Абонемент ($m)

Выполнил 3 разных теста для проверки серверного оборудования (тест 1С, тесты gilev) на возможное число 1С онлайн-пользователей одновременно работающих на нем и интерпретировал результаты тестов через легких, средних и тяжелых пользователей с помощью таблицы с профилями реальных пользователей.

3 стартмани

17.12.2019    12717    sapervodichka    3    

Простой способ индексирования интервалов Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

28.09.2016    40426    ildarovich    22    

Разбираемся с web-kit в 1С, на примере интеграции TinyMCE в управляемую форму в УТ 11.4. Допиливаем обмен с сайтом в УТ 11.4

Обмен данными 1С Интеграция Адаптация типовых решений v8 v8::УФ УТ11 Абонемент ($m)

Многие уже знают, что в релизе платформы 8.3.14.1565, браузер Internet Explorer был заменен на Web-Kit, это на самом деле большой шаг вперед, но я уверен, многим, как и мне, пока не совсем понятно, что к чему. Возник опыт использования web-kit в 1С, вызова JS из 1С и вызова 1С из JS. Давайте вместе попробуем понять, чем одно отличается от другого, и заодно сделаем, что-нибудь полезное. Да и наверняка многим придется переписывать свои подобные поделки после обновления на новую платформу, так что надеюсь мой опыт окажется полезным.

2 стартмани

08.12.2019    8877    Бэнни    25    

Массовое изменение режима поддержки объектов конфигурации

Структура метаданных v8 1cv8.cf Абонемент ($m)

Что делать, если при сравнении/объединении конфигураций нужно изменить режим поддержки для большого количества объектов? Штатного механизма для выполнения подобной задачи в Платформе нет. Изменять режим для всей конфигурации? Описывается способ, позволяющий выполнить изменение режима только для нужных объектов.

05.11.2019    4358    VKislitsin    6    

"Живые" картинки со Snap.SVG

Практика программирования WEB Работа с интерфейсом v8 Абонемент ($m)

В статье рассмотрен пример использования http-сервисов для визуализации данных

1 стартмани

24.10.2019    14178    blackhole321    7    

Бесплатная проверка контрагентов в ФНС (общий модуль с алгоритмом). На примере выводим статус в список справочника контрагентов Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Если вам интересно проверить контрагенте в ФНС, вам поможет данная публикация. Весь алгоритм работы строится на основе данных, полученных с сервиса http://npchk.nalog.ru совершенно бесплатно.

1 стартмани

01.02.2018    35954    rpgshnik    49    

Интеграция 1С с сайтом (магазином) WordPress (WooCommerce) с помощью Rest API сайта. Часть 1. Авторизация

WEB v8 Абонемент ($m)

Интеграция 1С с сайтом (магазином) WordPress (WooCommerce) с помощью функционала Rest API предоставляемого платформой (CMS) WordPress (WooCommerce). Без дополнительных приложений на PHP/вставьте сюда любой другой язык программирования/.

1 стартмани

12.10.2019    34888    osivv    34    

RLS - дубли условий в запросах к СУБД

Практика программирования Роли и права v8 v8::Права 1cv8.cf Абонемент ($m)

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

1 стартмани

07.10.2019    8907    geron4    4    

Вебхук. Путь Телеграма

Внешние источники данных Интеграция v8 Абонемент ($m)

Долгое (на самом деле нет) и нелегкое путешествие телеграма к неведомым (из за РКН) конфигурациям 1С. Памятка себе.

1 стартмани

03.10.2019    20246    platonov.e    26    

БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному Промо

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Абонемент ($m)

Очень много попадается странных решений, которые можно решить через БСП:Дополнительные отчеты и обработки. Я бы вообще БСП из-за этой подсистемы переименовал в «Большое Спасибо Программистам». Поработаем с подсистемой в части написания регламентных заданий.

1 стартмани

10.05.2018    47366    dsdred    43    

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

Обработка документов Практика программирования v8 ERP2 УТ11 КА2 Абонемент ($m)

Дальнейшее развитие темы фоновой обработки данных - проведение документов в потоках. Настройка параметров и запуск основного процесса (менеджера потоков). Разбивка документов для проведения на не связанные друг с другом наборы и запуск дополнительных фоновых заданий для отдельных потоков. Отслеживание выполнения каждого потока в родительском сеансе.

1 стартмани

17.09.2019    10225    ids79    46    

Описание формата внутреннего представления данных 1С в контексте обмена данными

Практика программирования Внешние источники данных v8 v8::УФ 1cv8.cf Абонемент ($m)

Фирма 1С не рекомендует использовать внутреннее представление данных для любых целей, которые отличны от обмена с 1С:Предприятием 7.7. Но сама возможность заглянуть на "внутреннюю кухню" платформы с помощью функций ЗначениеВСтрокуВнутр(), ЗначениеВФайл(), ЗначениеИзСтрокиВнутр() и ЗначениеИзФайла(), дала возможность сообществу программистов 1С разработать новые приемы разработки и анализа. Так, именно на использовании внутреннего представления был построен алгоритм "быстрого массива", который позволяет практически мгновенно создать массив в памяти на основании строки с разделителями. С помощью разбора внутреннего представления можно "на лету" программным кодом выполнить анализ обычной формы и даже сделать редактор графической схемы. Во внутреннем формате сохраняют свои данные между сеансами различные популярные внешние обработки. А еще это возможность сделать быстрый обмен с внешними системами.

1 стартмани

06.09.2019    20378    Dementor    30    

1С и PowerShell - обновление из хранилища

Администрирование данных 1С Инструментарий разработчика v8 Абонемент ($m)

Пример скрипта, упрощающего работу.

1 стартмани

29.08.2019    9318    Jokemas    31    

Некоторая работа с данными через COM Промо

Практика программирования v8 Абонемент ($m)

В статье приведены примеры работы с Платформой 8.X через COM (точнее, через объект COMConnector). Примеры кода были использованы при реализации прикладных задач в процессе трудовой деятельности.

2 стартмани

05.12.2012    58513    wowik    32    

Удобный просмотр результата запроса с большим количеством временных таблиц

Практика программирования v8 Абонемент ($m)

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

1 стартмани

27.08.2019    11519    ids79    22    

Обмен большими данными между клиентом и сервером

Внешние источники данных v8 Абонемент ($m)

В статье рассматривается вопрос передачи больших объемов данных, превышающих теоретический лимит сеансовых данных (4Гб за вызов) (они же временное хранилище) как с клиента на сервер, так и в обратном направлении.

1 стартмани

27.08.2019    14440    logos    32    

Запуск фонового задания во внешней обработке. Отключение предупреждений защиты от опасных действий в фоновом задании

Практика программирования v8 1cv8.cf Абонемент ($m)

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

2 стартмани

24.08.2019    12797    BenGunn    22    

Работа со схемой запроса Промо

Инструментарий разработчика Практика программирования v8 v8::Запросы Абонемент ($m)

Стандартом взаимодействия с реляционной базой данных стал язык SQL. Приемником SQL в 1С является язык запросов. Язык запросов, также как и SQL, является структурированным. Составляющие структуры запроса отвечают на разные вопросы о том, какие данные требуется получить и какие манипуляции с множествами данных необходимо произвести при получении. В простых случаях текст запроса можно написать вручную, однако в сложных случаях, а также при программном формировании, - лучше воспользоваться объектной моделью запроса и использовать объект "Схема запроса". В статье дается описание объектной модели и особенностей работы с ней, а также приводится решение, упрощающее взаимодействие с объектом "Схема запроса".

1 стартмани

24.04.2018    46333    kalyaka    35    

Изменяющееся контекстное меню в 1С 8.3

Практика программирования Работа с интерфейсом Разработка v8 v8::УФ Абонемент ($m)

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

1 стартмани

06.08.2019    17909    signum2009    16    

Использование HTTP-сервиса для создания "фронтенда" HTML/CSS/jQuery с кэшированием

WEB v8 1cv8.cf Абонемент ($m)

В статье описан способ создания "фронтенда" на HTML/CSS/jQuery и скрипт кеширования AJAX запросов на PHP.

1 стартмани

06.08.2019    14343    Sedaiko    25    

Менеджер потоков: реализация "любой" задачи в потоках

Производительность и оптимизация (HighLoad) Инструментарий разработчика v8 Абонемент ($m)

Менеджер потоков – один их новых инструментов, который упрощает работу разработчиков. Насколько легко с ним, на конференции Infostart Event 2018 Education показал начальник отдела автоматизации 1С Иван Филимонов компании «Трансстроймеханизация».

01.08.2019    10296    DarkAn    7    

Многопоточность. Универсальный «Менеджер потоков» (фреймворк) с отслеживанием зависимости объектов Промо

Практика программирования Математика и алгоритмы Универсальные функции Производительность и оптимизация (HighLoad) v8 1cv8.cf Россия Абонемент ($m)

Восстановление партий, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

26.05.2017    50054    DarkAn    86    

Процедура ПриКомпоновкеРезультата

Практика программирования v8 1cv8.cf Абонемент ($m)

Коллекция кода

1 стартмани

26.07.2019    45863    vasilev2015    64    

10 способов получить модуль числа (а может, и больше)

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

Пишем функцию вычисления модуля числа. Сколько способов существует? Давайте посчитаем!

1 стартмани

11.07.2019    10207    sam441    29    

Мониторинг производительности и искусственный интеллект

Производительность и оптимизация (HighLoad) Практика программирования Разработка v8 Абонемент ($m)

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

1 стартмани

01.07.2019    9706    ivanov660    28    

Агрегатное суммирование строк в запросе – сложно, но не невозможно Промо

Математика и алгоритмы v8 Абонемент ($m)

Описывается метод соединения строк из одной колонки таблицы в единую результирующую строку в запросе на языке 1С. Метод сложный и по сравнению с внезапросной техникой представляет больше спортивный, чем практический интерес.

1 стартмани

09.09.2013    80696    ildarovich    54    

"Убер на складе": динамический расчет маршрутов с учетом реальных расстояний

Учет ТМЦ Практика программирования Учет ТМЦ v8 УУ Абонемент ($m)

Представляю методику и инструмент для динамического расчета маршрутов отбора на высоконагруженных складах для максимального повышения эффективности склада, ускорения проходимости и, как следствие, экономии денег. Это методика и обработка для интеграции в WMS решения. Тестировалось на 1С 8.3.14.1565.

3 стартмани

24.06.2019    17684    informa1555    17    

1С:Ассемблер. Немного летнего веселья!

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

Все вы, наверное, слышали, что 1С-ники жалуются на свою систему, считая язык 1С недостаточно низкоуровневым, скучным и т.п. Все они с тоской поглядывают в сторону "настоящих" языков программирования. Так вот, господа, они неправы. В системе 1С есть места, где можно размять программерский мозг и получить удовольствие от низкоуровневой техники. Предлагаю вам погрузиться в недра виртуальной машины 1С и понять, как она работает. Там есть свой "ассемблер" и мы попробуем его в действии!

1 стартмани

21.06.2019    30990    Evil Beaver    143    

Простые примеры сложных отчетов на СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Подписи в отчете. Особенности соединения наборов: как соединить несоединяемое. Остатки на дату и обороты по месяцам в одном отчете. Курс валюты на каждую дату без группировок и соединений в запросе. Отчет с произвольными колонками и с произвольной последовательностью. "Неадекватный отчет".

1 стартмани

12.06.2019    32119    Hatson    31    

Новый запрос и новая таблица значений как функции Промо

Практика программирования v8 Абонемент ($m)

Предлагается две простые функции, использование которых уменьшает объем кода в конфигурациях на платформе «1С:Предприятие 8». Эти функции можно добавлять к своему общему модулю, что сделает процесс программирования более эффективным.

1 стартмани

27.11.2012    45633    ildarovich    46    

Работа с графической схемой в объектной модели DOM

Универсальные функции v8 v8::УФ Абонемент ($m)

Пример кода для работы с графической схемой в объектной модели DOM, платформа 8.3.12.

1 стартмани

04.06.2019    8147    botokash    19    

XDTO для чайников

Обмен через XML v8 1cv8.cf Абонемент ($m)

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

1 стартмани

29.05.2019    33898    HAMMER_59    39    

Отладка правил обмена КД2 для подсистемы БСП Обмен данными

Перенос данных из 1C8 в 1C8 v8 1cv8.cf Абонемент ($m)

Уже давно нельзя отлаживать правила обмена при помощи внешних файлов. Попробуем исправить это.

1 стартмани

27.05.2019    12708    fenixnow    8