Работа легендарной платформы 1С:Предприятие 7.7 в связке с современными версиями MS SQL Server (2012, 2014 и выше) часто сопровождается специфическими техническими проблемами. Одной из самых неприятных является ошибка «дублей ключей» при попытке перезаписи или проведения документа. Эта проблема связана с тем, что движок 7.7 не был рассчитан на механизмы работы современных СУБД, таких как измененная логика очистки записей и блокировок.
В этой статье мы подробно разберем, почему возникает эта ошибка и какие шаги необходимо предпринять, чтобы стабилизировать работу системы.
Для начала проанализируем ситуацию. В 1С 7.7 данные табличных частей документов хранятся в таблицах с префиксом DT*. Первичный ключ (Primary Key) в этих таблицах обычно состоит из двух полей: IDDOC (уникальный идентификатор документа) и LINENO (номер строки). Ошибка дублирования возникает в момент, когда 1С пытается вставить в таблицу новую строку с тем же сочетанием IDDOC и LINENO, которое, по мнению SQL Server, там уже существует.
Почему это происходит, если 1С перед записью должна очищать старые строки? Разберем основные факторы:
vk_sleep_1C.dll) может нарушать тайминги транзакций.Рассмотрим необходимые изменения в настройках самого SQL-сервера. Поскольку 1С 7.7 проектировалась под SQL 2000, нам нужно максимально приблизить поведение современных систем к старым стандартам в части блокировок.
Настройка MAXDOP: Установите параметр Maximum Degree of Parallelism в значение 1. Это заставит SQL Server выполнять операции последовательно, что критично для старого движка 1С. Это можно сделать через свойства сервера в SQL Server Management Studio (раздел Advanced) или командой:
EXEC sys.sp_configure N'show advanced options', N'1'
RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N'max degree of parallelism', N'1'
RECONFIGURE WITH OVERRIDE
GO
Параметры изоляции: Проверьте, чтобы для вашей базы данных были выключены режимы ALLOW_SNAPSHOT_ISOLATION и READ_COMMITTED_SNAPSHOT. Платформа 7.7 ожидает классическую блокировочную модель (Locking), а не версионную.
Проанализируем «зоопарк» используемых библиотек. В сообщении форума упоминается vk_sleep_1C.dll. Это устаревшее решение, которое часто становится причиной проблем на многоядерных серверах.
Рекомендация по замене: Выясним причину использования этой библиотеки. Обычно её ставят для снижения нагрузки на CPU. Однако в современных условиях лучше использовать компоненту V7AppProfile или встроенные средства последних версий 1CPP.dll.
Удалите vk_sleep_1C.dll и замените механизм ожидания захвата таблиц. В коде ПриНачалеРаботыСистемы можно принудительно установить время ожидания захвата таблиц в 0, что обеспечит максимально быструю реакцию системы без «подвисаний» в очередях блокировок.
Если ошибка сохраняется, рассмотрим программные методы обхода проблемы в коде 1С. Часто помогает временное «разведение» операций удаления и вставки записей.
Один из рабочих «костылей», упомянутых экспертами — это предварительное распроведение документа перед его изменением. Рассмотрим пример кода:
// В модуле формы документа перед записью
Процедура ПередЗаписьюДокумента()
Если Выбран() = 1 Тогда
Если Проведен() = 1 Тогда
СделатьНепроведенным();
// Это гарантирует, что SQL очистит записи в регистрах
// и подготовит таблицу DT к обновлению
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Также важно убедиться, что в свойствах документа установлена галочка «Автоматическая нумерация строк». Если она снята, и номер строки (LINENO) формируется вручную в коде, проверьте алгоритм на наличие дублей. При использовании метода ВыгрузитьТабличнуюЧасть() и последующей загрузки обратно, номера строк могут сбиваться, если не очищать таблицу полностью.
Посмотрим на ситуацию со стороны базы данных. Иногда дубли ключей возникают из-за повреждения индексов или устаревшей статистики.
Регулярно выполняйте переиндексацию таблиц документов. Для этого можно использовать следующий скрипт в SQL Management Studio:
-- Перестроение всех индексов в базе данных
EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? REBUILD'
-- Обновление статистики
EXEC sp_updatestats
Это поможет SQL-серверу быстрее находить и удалять те самые «записи-призраки», освобождая место для новых данных документа.
Для программистов, работающих с высоконагруженными базами 7.7, крайне рекомендуется использование компоненты TurboMD. Это позволяет вносить изменения в структуру и код без выгона всех пользователей из базы. Как отмечалось в обсуждении, правильная связка 1CPP + TurboMD + FormEx позволяет современным системам на базе 7.7 работать стабильно даже на MS SQL 2019.
Подведем итог: проблема «дублей ключей» — это комплексная ошибка. Для её решения мы должны объединить настройку параметров СУБД (MAXDOP), аудит внешних компонент (отказ от старых патчей Romix в пользу современных 1CPP) и, в крайнем случае, адаптацию кода проведения документов.