Каждый системный администратор и разработчик 1С рано или поздно сталкивается с ситуацией, когда стабильно работавшая система начинает давать сбои. Особенно неприятно, когда это происходит в разгар рабочего дня в торговой точке, работающей на базе 1С:Розница. Ошибки типа «Конфликт блокировок при выполнении транзакции» и внезапные обрывы соединений с сообщением «Сеанс отсутствует или удален» могут парализовать работу касс и складов.
В этой статье мы подробно разберем, как решить эти проблемы в связке 1С:Предприятие 8.2 / 8.3 и MS SQL Server Express. Мы детально проанализируем сетевые настройки сервера, разберем ошибки авторизации Windows, научимся настраивать технологический журнал для поиска виновников блокировок, настроим планы обслуживания для бесплатной СУБД и оптимизируем конфигурацию 1С.
---
Проанализируем классическую ситуацию: на сервере установлены две сетевые карты (для локальной сети и внешнего контура или резервного провайдера), а также активен протокол IPv6. В такой конфигурации служба ragent (Агент сервера 1С) может вести себя непредсказуемо, хаотично связывая рабочие процессы с разными IP-адресами. Это приводит к тому, что рабочий процесс rphost внезапно теряет связь с клиентским приложением, вызывая ошибку «Сеанс отсутствует или удален». При этом незавершенные транзакции аварийно завершенных сеансов могут оставлять таблицы СУБД заблокированными, вызывая у остальных пользователей тайм-ауты блокировок.
Часто системные администраторы пытаются решить проблему простым отключением IPv6 в свойствах сетевого адаптера. Однако делать это крайне не рекомендуется. В современных операционных системах Windows на протокол IPv6 завязано множество внутренних служб безопасности, авторизации и кластеризации. Полное отключение может привести к нестабильной работе самой ОС.
Рассмотрим правильный подход — программную приоритизацию протокола IPv4 над IPv6 через реестр Windows. Разберем по шагам, как это сделать:
netsh interface ipv6 set prefix ::/96 60 3
netsh interface ipv6 set prefix ::ffff:0:0/96 55 4
Если на сервере физически установлены две сетевые карты, необходимо жестко привязать службу 1С к конкретному IP-адресу. Для этого выполним следующие действия:
regedit.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\1C:Enterprise 8.x Server Agent (название ветки зависит от версии платформы).ImagePath и отредактируем его, добавив явное указание IP-адреса и диапазона портов. Например, добавим ключ -regport 1541 -port 1540 -range 1560:1591 и укажем конкретный IP-адрес через параметры запуска, чтобы предотвратить метания службы между сетевыми картами.hosts на самом сервере 1С и на рабочих станциях пользователей. Файл находится по пути: C:\Windows\System32\drivers\etc\hosts. Пример записи:
192.168.1.100 My1CServer
---
Когда в логах Агента сервера 1С (ragent) появляются записи вида InitializeSecurityContext: Error 80090301!, это свидетельствует о серьезных сбоях в работе механизма сквозной Windows-авторизации (SSPI).
Выясним причину этой ошибки. Код 80090301 в терминологии Windows API расшифровывается как SEC_E_INVALID_HANDLE (недействительный дескриптор безопасности). Когда пользователь пытается войти в 1С с доменной учетной записью, платформа обменивается билетами безопасности Kerberos или NTLM с контроллером домена. Если из-за сетевых «скачков» между сетевыми картами или конфликта протоколов IPv4/IPv6 соединение прерывается хотя бы на долю секунды, установленный дескриптор безопасности аннулируется. Служба 1С теряет контекст авторизации, аварийно завершает сеанс и записывает ошибку в лог.
Чтобы исправить это, помимо стабилизации сети, необходимо проверить права учетной записи, под которой запускается служба сервера 1С (dbms). Если служба работает под доменной учетной записью, для нее обязательно должны быть зарегистрированы имена субъектов-служб (SPN) в Active Directory. В противном случае механизм авторизации будет постоянно сваливаться с Kerberos на менее стабильный NTLM. Регистрация SPN выполняется администратором домена через командную строку утилитой setspn:
setspn -A MSSQLSvc/My1CServer.domain.local:1433 domain\1c_service_user
setspn -A My1CServer/My1CServer.domain.local:1541 domain\1c_service_user
---
Когда пользователи жалуются на превышение максимального времени ожидания блокировки, бессмысленно гадать, какой именно документ или отчет вызывает проблему. Нам нужен точный инструмент диагностики. Таким инструментом является Технологический журнал 1С.
Настроим сбор информации по блокировкам. Для этого в каталоге настроек платформы (обычно это C:\Program Files\1cv8\conf\ или C:\Program Files (x86)\1cv8\conf\) создадим текстовый файл с именем logcfg.xml. Запишем в него конфигурацию, которая будет фиксировать события таймаутов блокировок (TTIMEOUT) и управляемых блокировок (TLOCK):
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\v8logs\locks" history="24">
<event>
<eq property="Name" value="TTIMEOUT"/>
</event>
<event>
<eq property="Name" value="TLOCK"/>
<eq property="p:processName" value="Retail"/>
</event>
<property name="all"/>
</log>
</config>
Важно: Убедитесь, что у пользователя, под которым запущена служба сервера 1С, есть полные права на запись в каталог C:\v8logs\locks. Анализируя файлы логов из этой папки, мы сможем увидеть точный контекст исполнения кода 1С, вызывающий конфликт: имя модуля, номер строки и метаданные заблокированного объекта (например, регистр накопления РегистрНакопления.ТоварыНаСкладах).
---
Использование бесплатной СУБД MS SQL Server 2008/2012/2016/2019 Express накладывает жесткие рамки на производительность системы:
При дефиците оперативной памяти СУБД вынуждена постоянно сбрасывать кэш планов запросов и читать данные напрямую с диска. Если при этом таблицы базы данных не оптимизированы, любая транзакция начинает выполняться крайне медленно, удерживая блокировки на таблицах слишком долго.
Главная проблема версии Express — отсутствие службы SQL Server Agent, из-за чего невозможно стандартными средствами настроить регулярное обслуживание базы данных. Без регулярного обновления статистики оптимизатор SQL Server строит неверные планы выполнения запросов. Вместо быстрого точечного поиска по индексу (Index Seek) СУБД выполняет полное сканирование таблиц (Table Scan или Index Scan), накладывая монопольные блокировки на огромные диапазоны данных.
Разберем, как обойти это ограничение и настроить автоматическое обслуживание с помощью встроенного Планировщика задач Windows (Task Scheduler) и утилиты командной строки sqlcmd.
Напишем скрипт для обновления статистики и реиндексации таблиц базы данных. Создадим файл db_maintenance.sql в корне диска C:\:
USE [Имя_Вашей_Базы_Данных];
GO
-- Обновление статистики для всех таблиц с полным сканированием данных
EXEC sp_MSforeachtable 'UPDATE STATISTICS ? WITH FULLSCAN';
GO
-- Перестроение и дефрагментация индексов при высоком уровне фрагментации
DECLARE @TableName varchar(255);
DECLARE @SqlCommand varchar(1000);
DECLARE TableCursor CURSOR FOR
SELECT REPLICATE('[', 1) + s.name + '].[' + t.name + ']' as TableName
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id;
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SqlCommand = 'ALTER INDEX ALL ON ' + @TableName + ' REORGANIZE;';
EXEC(@SqlCommand);
FETCH NEXT FROM TableCursor INTO @TableName;
END;
CLOSE TableCursor;
DEALLOCATE TableCursor;
GO
Для автоматического запуска этого скрипта создадим в Планировщике задач Windows новую задачу, которая будет запускаться каждую ночь. В поле "Действие" укажем запуск программы со следующими аргументами:
sqlcmd-S localhost\SQLEXPRESS -E -i "C:\db_maintenance.sql"Регулярное выполнение этого скрипта (каждую ночь или хотя бы раз в неделю) гарантирует, что планы запросов всегда будут оптимальными, а время наложения транзакционных блокировок снизится до минимума.
---
Для радикального снижения количества конфликтов блокировок между читающими и пишущими транзакциями (например, когда кассир проводит чек, а в это время бухгалтер формирует тяжелый отчет по остаткам) можно использовать механизм Read Committed Snapshot Isolation (RCSI).
При включенном RCSI читающие транзакции не блокируют пишущие, а пишущие не блокируют читающие. Вместо ожидания освобождения заблокированной строки SQL Server предоставляет читающему процессу ее старую версию из системной базы данных tempdb (версионирование строк).
Прежде чем включить этот режим, выполним проверку режима блокировок в самой 1С. Важно: Включение RCSI настоятельно рекомендуется только в том случае, если ваша конфигурация переведена на Управляемый режим блокировок. Если конфигурация до сих пор использует Автоматический режим блокировок (что часто встречается в старых, доработанных версиях «Розницы 2.0» на платформе 8.2), включение версионирования на уровне SQL может привести к логическим ошибкам учета, например, к списанию товаров в «минус» из-за того, что СУБД проигнорирует внутренние ожидания блокировок платформы.
Если конфигурация подготовлена и переведена на управляемый режим, включим RCSI с помощью SQL-запроса:
-- Переводим базу данных в однопользовательский режим для сброса активных сессий
ALTER DATABASE [Имя_Вашей_Базы_Данных] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
-- Включаем параметр READ_COMMITTED_SNAPSHOT
ALTER DATABASE [Имя_Вашей_Базы_Данных] SET READ_COMMITTED_SNAPSHOT ON;
GO
-- Возвращаем многопользовательский режим
ALTER DATABASE [Имя_Вашей_Базы_Данных] SET MULTI_USER;
GO
---
Даже самые лучшие настройки сети и СУБД не помогут, если прикладной код конфигурации написан неоптимально. Рассмотрим встроенные механизмы платформы 1С, помогающие бороться с блокировками в розничной торговле.
Основным «узким горлышком» при проведении документов продажи является таблица итогов регистров накопления (например, ТоварыНаСкладах или РасчетыСКлиентами). Когда несколько касс одновременно проводят чеки, они пытаются изменить одну и ту же физическую строку остатка конкретного товара на складе, выстраиваясь в очередь.
Разберем, как решить эту проблему в Конфигураторе:
После этого платформа начнет записывать изменения остатков в разные физические строки с использованием специального разделителя. При формировании отчетов система автоматически суммирует эти строки. Это позволяет кассирам проводить документы параллельно, не блокируя друг друга.
В старых версиях конфигураций использовался так называемый классический режим проведения: при перепроведении документа платформа сначала полностью удаляла его старые движения из таблиц регистров, затем заново считывала остатки (чтобы проверить, хватает ли товара) и записывала новые движения. Это приводило к очень длинным транзакциям и массовым блокировкам.
Проанализируем преимущества нового режима проведения («Запись движений без предварительного удаления»):
Рекомендуется убедиться в свойствах документов (например, Документ.ОтчетОРозничныхПродажах, Документ.РеализацияТоваровУслуг), что свойство «Записывать движения при проведении» установлено в значение Записывать выбранные или Записывать модифицированные, а алгоритм проведения не выполняет лишних запросов к СУБД внутри транзакции.
---
Подводя итог, можно сказать, что стабильная работа 1С в клиент-серверном варианте — это результат синергии правильных настроек сетевой инфраструктуры ОС, регулярного обслуживания СУБД и грамотной архитектуры метаданных самой конфигурации. Выполнив приоритизацию сетевых интерфейсов, настроив планы обслуживания SQL и включив разделение итогов, вы обеспечите высокую скорость и непрерывность бизнес-процессов вашей компании.