Не удается получить ресурс lock в данный момент времени 1с

Обновлено: 04.07.2024

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

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

В случае SQL-сервером, это сделать наконец-то удалось. Приведенный ниже код SQL-запроса уже неоднократно помогал мне найти условного "виновника" (условного потому что виноват не пользователь, а программист который написал "кривой" или неоптимизированный код). Надеюсь поможет в работе многим. Код только частично мой, в основном был собран из разных источников с простора интернета, но к сожалению ссылок не сохранилось.

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

В повседневной работе достаточно задействовать только первый блок "/*кто кого*/". Открываем MS SQL Server Management Studio, правой на корень - "new query" - вставляем код запроса (только верхнюю часть до "Кто что блокирует", остальное - для детального анализа), выполняем запрос (вверху есть кнопочка выполнения запроса).

Выполнив запрос, запоминаем "ID виновника", быстренько идем в консоль сервера 1С, заходим в ветку "Сеансы" нашей базы. Видим все соединения с 1С-сервером, ищем там колонку "Соединение с СУБД", чтобы увидеть соединения 1С-сервера с MSSQL-сервером. В колонке будет всего несколько заполненных значений, среди них и будет "ID виновника".

Что делать если его там нет, тут 3 варианта:

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

2. Сеанс который блокирует MSSQL находится в другой базе т.е. блокировка не в той базе (можно попробовать задействовать ветку всех сеансов в консоли 1С-сервера) - вернитесь в MSSQL и внимательно посмотрите в колонку DB в ней находится название базы.

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

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

Оригинальная версия продукта: SQL Server
Исходный номер КБ: 323630

Определите, вызывает ли эскалация блокировки блокировку

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

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

Дополнительные сведения о том, как идентифицировать главный блокатор и ресурс блокировки, которые удерживаются главным блокатором и блокируют другие идентификации процессов сервера (SPID), см. в журнале INF: Understanding and resolving SQL Server блокировки.

Если блокировка, блокирующая других пользователей, не является блокировкой TAB (на уровне таблицы), которая имеет режим блокировки S (общий) или X (эксклюзивный), эскалация блокировки не является проблемой. В частности, если блокировка TAB — это блокировка намерения (например, режим блокировки is, IU или IX), это не вызвано эскалацией блокировки. Если проблемы блокировки не вызваны эскалацией блокировки, см. в статью INF: Understanding and resolving SQL Server устранение неполадок.

Предотвращение эскалации блокировки

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

Разорвать крупные пакетные операции на несколько меньших операций. Например, вы запустите следующий запрос, чтобы удалить из таблицы аудита более 100 000 старых записей, а затем определите, что запрос вызвал эскалацию блокировки, которая заблокировала других пользователей:

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

Уменьшите след блокировки запроса, сделав его максимально эффективным. Большие проверки или множество закладки могут увеличить вероятность эскалации блокировки. Кроме того, они увеличивают вероятность заторов и отрицательно влияют на производительность и конвалютию. После определения того, что запрос, вызывающий эскалацию блокировки, ищите возможности для создания новых индексов или добавления столбцов в существующий индекс, чтобы удалить проверки индекса или таблицы и максимально повысить эффективность поиска индекса. Просмотрите план выполнения и, возможно, создайте новые непрорабационные индексы для повышения производительности запросов. Дополнительные сведения см. в SQL Server Index Architecture and Design Guide.

Одна из целей этой оптимизации заключается в том, чтобы сделать индекс стремится вернуть как можно меньше строк, чтобы свести к минимуму затраты на поиск закладок (максимальное избирательность индекса для запроса). Если SQL Server, что логический оператор Lookup закладки возвращает много строк, он может использовать пункт для того, чтобы сделать вид PREFETCH закладки. Если SQL Server используется для считывательных закладки, он должен увеличить уровень изоляции транзакции части запроса до "повторяемого чтения" для части PREFETCH запроса. Это означает, что то, что может выглядеть как заявление на уровне изоляции с "чтением", может получить несколько тысяч замков ключей (как для кластерного индекса, так и для одного ненастройного SELECT индекса). Это может привести к превышению пороговых значений эскалации блокировки. Это особенно важно, если вы найдете, что эскалация блокировки является общей блокировкой таблицы, хотя они обычно не видны на уровне изоляции по умолчанию "считывуемой". Если в результате эскалации возникает оговорка "Поиск закладки", рассмотрите возможность добавления столбцов в неиспользуемый индекс, который отображается в индексе Seek, или логического оператора проверки индекса ниже логического оператора Поиска закладок в плане PREFETCH запросов. Можно создать индекс покрытия (индекс, который включает все столбцы в таблице, которая использовалась в запросе), или, по крайней мере, индекс, который охватывает столбцы, которые использовались для критериев крупации или в пункте WHERE, если нецелесообразно включать все в список "выберите столбец".

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

Эскалация блокировки не может произойти, если другой SPID в настоящее время удерживает несовместимый блокировку таблицы. Эскалация блокировки всегда перерастает в блокировку таблицы, а не в блокировку страницы. Кроме того, если попытка эскалации блокировки не удалась из-за того, что другой SPID содержит несовместимый блокировку TAB, запрос, который пытался эскалацию, не блокируется в ожидании блокировки TAB. Вместо этого он продолжает приобретать блокировки на исходном, более гранулированном уровне (строка, ключ или страница), периодически делая дополнительные попытки эскалации. Таким образом, одним из способов предотвращения эскалации блокировки на определенной таблице является приобретение и удержание блокировки на другом соединении, которое не совместимо с типом эскалаторного блокировки. Блокировка IX (эксклюзивного намерения) на уровне таблицы не блокирует ни строки, ни страницы, но по-прежнему не совместима с замком TAB с эскалацией S (общий) или X (эксклюзивный). Например, предположим, что необходимо выполнить пакетное задание, которое изменяет многие строки в таблице митируемых и вызываемых блокированием из-за эскалации блокировки. Если эта работа всегда завершается менее чем за час, можно создать задание Transact-SQL, содержаное следующий код, и запланировать начало нового задания за несколько минут до начала пакета:

Этот запрос приобретает и удерживает блокировку IX в mytable в течение одного часа. Это предотвращает эскалацию блокировки на столе в течение этого времени. Эта партия не изменяет данные и не блокирует другие запросы (если другой запрос не заставляет блокировку таблицы с помощью подсказки TABLOCK или если у администратора отключены страницы или блоки строк с помощью ALTER INDEX).

Устранение эскалации блокировки, вызванной отсутствием SARGability, термином базы данных, используемым для описания того, может ли запрос использовать индексы для предикатов и присоединяться к столбцам. Дополнительные сведения о SARGability см. в сайте Inside Design Guide Query Considerations. Например, довольно простой запрос, который, как представляется, не запрашивает многие строки или, возможно, одну строку, может по-прежнему сканировать всю таблицу/индекс. Это может произойти, если в левой части клаузула WHERE есть функция или вычисления. Такие примеры, в которых отсутствует sarGability, включают неявные или явные преобразования типа данных, функцию системы ISNULL() , функцию, определяемую пользователем, с столбцом, переданным в качестве параметра, или вычисления в столбце, например или WHERE CONVERT(INT, column1) = @a WHERE Column1*Column2 = 5 . В таких случаях запрос не может искать существующий индекс, даже если он содержит соответствующие столбцы, так как все значения столбцов должны быть извлечены сначала и переданы функции. Это приводит к сканированию всей таблицы или индекса и приводит к приобретению большого количества блокировок. В таких условиях SQL Server может достичь порогового значения эскалации для подсчета блокировки. Решение заключается в том, чтобы не использовать функции для столбцов в пункте WHERE, обеспечивая условия SARGable.

Отключение эскалации блокировки

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

  • Уровень таблицы: Можно отключить эскалацию блокировки на уровне таблицы. См. ALTER TABLE . SET (LOCK_ESCALATION = DISABLE) . Чтобы определить, какую таблицу нацелить, изучите запросы T-SQL. Если это невозможно, используйте расширенные события,в lock_escalation событие и изучите столбец object_id. Кроме того, используйте событие Lock:Escalation и изучите столбец с ObjectID2 помощью SQL Profiler.
  • Уровень экземпляра: Вы можете отключить эскалацию блокировки, включив флаг трассировки 1211 для экземпляра. Однако этот флаг трассировки отключает всю эскалацию блокировки во всем мире в экземпляре SQL Server. Эскалация блокировки служит полезной цели в SQL Server за счет максимальной эффективности запросов, которые в противном случае замедляются из-за накладных расходов на приобретение и освобождение нескольких тысяч замков. Эскалация блокировки также помогает свести к минимуму требуемую память, чтобы отслеживать блокировки. Память, которую SQL Server динамически распределить для структур блокировки, является конечной. Поэтому, если отключить эскалацию блокировки и объем памяти блокировки будет достаточно большим, любая попытка выделить дополнительные блокировки для любого запроса может привести к сбойу и создать следующую запись ошибки:

Ошибка: 1204, серьезность: 19, состояние: 1
В SQL Server не удается получить ресурс LOCK. Повторяйте свое заявление, если активных пользователей меньше, или попросите системного администратора проверить SQL Server блокировки и конфигурации памяти.

При ошибке 1204 она останавливает обработку текущего заявления и вызывает откат активной транзакции. Откат сам по себе может заблокировать пользователей или вызвать длительное время восстановления базы данных, если перезапустить SQL Server службу.

Этот флаг трассировки (-T1211) можно добавить с помощью диспетчер конфигурации SQL Server. Необходимо перезапустить службу SQL Server, чтобы новый параметр запуска вступил в силу. При запуске DBCC TRACEON (1211, -1) запроса флаг трассировки вступает в силу немедленно.
Однако если не добавить параметр запуска -T1211, при перезапуске службы SQL Server теряется DBCC TRACEON эффект команды. Включение флага трассировки предотвращает любые будущие эскалации блокировки, но не отменяет эскалации блокировки, которые уже произошли в активной транзакции.

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

Пороговые значения эскалации блокировки

Эскалация блокировки может возникать при одном из следующих условий:

Порог памяти достигнут . Порог памяти достигает 40 процентов памяти блокировки. Если объем памяти блокировки превышает 24 процента буферного пула, можно вызвать эскалацию блокировки. Память блокировки ограничена 60 процентами видимого буферного пула. Порог эскалации блокировки установлен на уровне 40 процентов памяти блокировки. Это 40 процентов из 60 процентов буферного пула или 24 процента. Если память блокировки превышает 60-процентное ограничение (это гораздо более вероятно, если эскалация блокировки отключена), все попытки выделить дополнительные блокировки сбой, и создаются 1204 ошибки.

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

Чтобы понять, какой порог был достигнут, используйте расширенные события, в lock_escalation событие и изучите escalated_lock_count и escalation_cause столбцы. Кроме того, используйте событие Lock:Escalationи изучите значение, в котором значение "0 - LOCK_THRESHOLD" указывает на превышение порога блокировки, а "1 - MEMORY_THRESHOLD" указывает, что это утверждение превысило пороговое значение EventSubClass памяти. Кроме того, изучите IntegerData IntegerData2 столбцы и столбцы.

Рекомендации

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

Количество пользователей нашей основной базы данных активно увеличивается за счет слияния второстепенных баз. Динамика примерно такая: 2020 – 150, 2021 – 300, 2022 – 500 (план). Поэтому оптимизация и быстродействие для нас важны: при увеличении числа пользователей проблемы растут нелинейно. Одно время даже хотели заключить договор ЦКТП, но пока справляемся своими силами.

Был один случай..

.. участились ошибки блокировки СУБД.



Анализ типов блокировок на сервере СУБД (за пол-дня). Ожидания LCK _ M _ X , LCK _ M _ U занимают доминирующие позиции.


Что делать ?

3-4 Поиск блокировок по dmv

4-5 Причина блокировок - отсутствует подходящий индекс

5-8 План запроса, поиск запроса в 1С, используя logcfg

10-12 Заключение, контакты

Решил посмотреть в СУБД. В ован запрос

представление sys.dm_exec_requests п оказывает выполняемые запросы в реальном времени, оно содержит поле blocking_session_id которое указывает на блокирующую сессию. (Доступна

Как я уже говорил, у нас большая компания с развитой инфраструктурой. Физически невозможно иметь доступ ко всем серверам компании. Получение информации с сервера целевой СУБД — через системного администратора. Поэтому просматривать состояние базы данных в реальном времени с помощью динамических представлений было неудобно. Мы не знали - в какой момент происходит блокировка. Договорились, что системный администратор соберет extended events по описанию (Спасибо, Юрий Пермитин) но напрямую задачу решить не удалось — события блокировок в СУБД происходят настолько часто, что производительность сервера упала. Составил более подробное описание, с фильтрами по длительности.

События lock_timeout, фрагменты sql_text

1. DELETE FROM T1 FROM dbo._InfoRg18447 T1 WHERE (T1._Fld18454RRef = @P1) AND (T1._Fld1420 = @P2)

С помощью функции ПолучитьСтруктуруБазыДанных() нашел имя регистра и имя поля. Как вы догадываетесь, индекс поля отсутствует. Очень похоже на ситуацию из видео на минуте 7. Для поля поставил значение «индексировать», флаг «ведущее» использовать не стал: могут быть пустые значения. Кстати, до добавления индекса события lock_deadlock на таблице dbo._InfoRg18447 тоже происходили. Причина блокировок СУБД подробно описана в видео: отсутствует индекс, происходит сканирование (с захватом) всей таблицы в режиме исключительной блокировки. При этом управляемые блокировки не учитывают план запроса, блокируют по значениям конкретных полей, конфликта между ними не происходит.

2. UPDATE T1 SET _Description = @P1, …. FROM dbo._ScheduledJobs31390 T1 WHERE T1._ID = @P15 AND T1._Version = @P16

3. Было несколько ошибок блокировок, связанных с шиной обмена Datareon . При зависании службы шины, отслеживаемые события в 1С не записывались, создавали lock_timeout. Эта ситуация была исправлена без моего участия.

События lock_escalation

Иногда происходит эскалация при работе с ценами по регистру «Цены номенклатуры» и табличной части документа «Установка цен». Документы больше 5000 строк табличной части, решение этой проблемы лежит в области организации процессов.

Итоги работы

Стало заметно лучше. Ниже анализ ожиданий на сервере СУБД за неделю, суммарная длительность ожиданий LCK _ M _ X , LCK _ M _ U составляет 18 минут, до начала работ суммарная длительность ожиданий могла быть до 2 часов в день.


P.S. Чтобы счастье было полным

настроил технологический журнал для dbmslocks (важно, что события собираются без отборов).

Есть один способ эффективно находить информацию на сайте ITS.



lka=‘1’ поток является источником блокировки.

lkp=‘1’ поток является жертвой блокировки.

lkpid номер запроса к СУБД, «кто кого заблокировал» (только для потока-жертвы блокировки).

lkaid список номеров запросов к СУБД, «кто кого заблокировал» (только для потока-источника блокировки).

lksrc номер соединения источника блокировки, если поток является жертвой.

lkpto время в секундах, прошедшее с момента обнаружения, что поток является жертвой.

lkato время в секундах, прошедшее с момента обнаружения, что поток является источником блокировок.

Файлы по часам получились более 6 Гб, поэтому для выделения информации использовал bash:

Для строчек, содержащих lkaid / lkpid выбрать 20 строк сверху и снизу, поместить в файл. Ниже пример: два источника, одна жертва. Ожидание длилось 0,84 секунды, прежде чем команда ПланыОбмена.ЗарегистрироватьИзменения() дождалась освобождения ресурса и установила блокировку.

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

Ошибка при выполнении операции с информационной базой server_addr=tcp://s150004:1541 descr=Ошибка сетевого доступа к серверу (Windows Sockets – 10060(0x0000274C). Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-зи неверного отклика уже подключенного компьютера. ) line=567 file=.\src\DataExchangeTcpClientlmpl.cpp.

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

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

пул соединений этого сервера - обычно от 1560 до 1590 диапазон.

Похоже, что полноценным правопреемником ТОПовой ошибки 80070005 в 8.0 стала ошибка 11004 в 8.1

Что имеем на сегодняшний день (если конечно разработчики не пересмотрят подход к работе с tcp/ip):

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

Проверить, присутствует ли имя компьютера центрального сервера в DNS или в файле C:\WINNT\system32\drivers\etc\hosts.

ping имя_машины - должен определиться ip-адрес

также убедиться что определение Ip-адреса имени <имя машины> и <имямашины>.<имя домена> выполняется не по разному.

Убедится, что агент сервера 1С:Предприятия 8.1 запущен (процесс ragent в Task Manager).
Проверить совпадение портов, указанного в параметре port командной строки запуска сервиса агента сервера и заданного в диалоге параметров центрального сервера консоли кластеров.

- Остановите сервис 1C:Enterprise 8.1 Server Agent.
- Убедитесь, в Task Manager, что все процессы ragent, rmngr, rphost завершились. При необходимости завершите их при помощи Task Manager.
- Откройте свойства сервиса 1C:Enterprise 8.1 Server Agent.
- Обратите внимание на строку Path to executable. В ней имеется параметр -d, за которым следует каталог данных кластера. Все файлы, относящиеся к кластеру, находятся в этом каталоге.
- Удалите все содержимое этого каталога.
- Запустите сервис 1C:Enterprise 8.1 Server Agent.
- Убедитесь, в Task Manager, что все процессы ragent, rmngr, rphost стартовали.
- Запустите консоль кластера и зарегистрируйте в ней центральный сервер. Консоль должна подсоединиться к центральному серверу и показать один кластер, созданный по умолчанию.

Производились ли какие-нибудь изменения в правах пользователя usr1cv81?

Ошибка:
Ошибка при выполнении операции с информационной базой
server_addr=tcp://server-1S:1541 descr=Ошибка сетевого доступа к серверу
(Windows Sockets - 10060(0x0000274C)Попытка установить соеденение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или былоразорвано уже установленое соеденение из-за неверного отклика уже подключенного компьютера.)
line=569 file=.\src\DataExchangeTcpClientlmpl.cpp

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



Имеем MS SQL Server 2008 R2

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

3 млн строк (нужный объем), при выполнении в MS SQL Server Management Studio.
Запрос выполняется без ошибок.

Есть пакет из нескольких инструкций:

На моменте выполнения запроса INSERT этих 3 млн записей возникает ошибка:

Экземпляру компонента SQL Server Database Engine не удается получить ресурс LOCK в данный момент времени.
Запустите инструкцию повторно, когда число активных пользователей уменьшится.
Попросите администратора баз данных проверить конфигурацию блокировки и памяти для данного экземпляра
либо выполнить проверку давно выполняющихся транзакций.

Добавлено 01.07.13, 06:19
Да, проблема начала появляться спустя

2 лет работы без проблемной работы, буквально пару дней назад.

А зачем Вы используете в качестве временной статическую таблицу?



И разумеется у меня в этот момент на сервере минимум народа (3 утра ).
То есть

происходит не поэтому.

Добавлено 01.07.13, 06:23

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

Хорошо. Второй вопрос - нахрена дропать таблицу, когда есть вкусный TRUNCATE TABLE?

Добавлено 01.07.13, 06:31
Третий вопрос - откуда вообще выплывает лок при инсерте? в какой обвязке происходит всё это?



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

2 года назад. У нас это "исторически сложившееся".
Уже исправил код так, что бы если таблица существовала - она трункейтилась, а если нет - создавалась.

Проблема все равно осталась.

Третий вопрос - откуда вообще выплывает лок при инсерте?

Если б я знал, наверное не обращался бы сюда.

Эммм? Вы имеете ввиду, наверное в каком окружении и когда это происходит?

У нас есть джоб MS SQL агента, в одном из его шагов, вот это.

Добавлено 01.07.13, 06:41
Да, это происходит не только в момент работы джоба в 3 утра, но и сейчас при выполнении из среды MS SQL Server Management Studio.



Мож, репорт можно из грязных данных состряпать? Попробуй (nolock) или SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.



Точно только один процесс дергает эту таблицу? Сетевики не бэкапят вместе с Вами?

Я вообще не вижу никакой необходимости заворачивать этот инсерт в транзакцию. Зачем? Чтобы нажить себе геморроев - в форме тех же самых локов?

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



INSERT INTO dbo.rt_tst_s2(WHS_ID, WHS_CODE, ART_CAT_ID) FROM Sources.dbo.WAREHOUSE WAR ,Sources.dbo.ART_CAT_BY_LEVEL CAT

Но не думаю, что он вам поможет.

Добавлено 01.07.13, 07:09

Попробуй (nolock) или SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Тот же результат для обоих вариантов.

Точно только один процесс дергает эту таблицу? Сетевики не бэкапят вместе с Вами?

Точно только один. Админы бэкапы делают поздно вечером. Уже к 00:00 у нас все начинается и нормально работает. Но вот это сломалось пару дней назад.

Добавлено 01.07.13, 07:17
Произвел следующий эксперимент - прямо сейчас создал таблицу, которую никто точно использовать не может, т к не знает о ее существовании, сделал туда этот же инсерт - та же проблема.
Возможно как-то нарушена целостность источников? Как бы это проверить?

Первое - сколько записей всего в таблице WAREHOUSE?
Второе - сколько из них отбирается фильтрацией по указанным полям? и есть ли там соотв. индекс?
Третье - сколько записей в таблице ART_CAT_BY_LEVEL? И насколько она статична?

Попробуйте завести промежуточную темп-таблицу, и сливать в неё фильтрованную выборку из WAREHOUSE. А потом уже множить ART_CAT_BY_LEVEL на эту выборку.

Хотя логика получения СТАТИЧЕСКОГО набора записей, полученного декартом, мне недоступна.

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

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

Добавлено 01.07.13, 07:20

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

Так у тебя проблема не в блокировании целевой таблицы, а в блокировании таблиц-источников.

Читайте также: