В практике администрирования и разработки на платформе «1С:Предприятие» иногда возникает мистическая ситуация: пользователь создает документ, нажимает кнопку экспорта во внешнюю систему, данные успешно уходят на устройство или в анализатор, но сам документ в базе 1С бесследно исчезает. При этом в системе образуется «дыра» в автонумерации (пропущен очередной номер), права на удаление у пользователей отобраны, а в ЖурналРегистрации не записывается никаких событий удаления. В этой статье мы подробно разберем, куда деваются такие документы, почему это происходит и как гарантированно поймать этого «барабашку» техническими средствами.
Проанализируем классическую ситуацию: документы пропадают именно в начале рабочего дня (первые за день, особенно часто в пятницу и понедельник). Это самый верный признак того, что у кого-то из пользователей или на одном из терминальных серверов (RDP) сбилось системное время или некорректно синхронизировался часовой пояс.
Выясним причину, как это работает на практике:
№3151).Записать(). Документ успешно записывается в базу данных СУБД с неверной датой (например, вчерашней).Рассмотрим, как проверить эту гипотезу. Нам нужно найти документ в базе данных исключительно по его номеру, без привязки к дате. Напишем простейший запрос в консоли запросов 1С:
ВЫБРАТЬ
Ссылка,
Дата,
Проведен,
ПометкаУдаления
ИЗ
Документ.НашИскомыйДокумент
ГДЕ
Номер ПОДОБНО "%3151%"
Если запрос возвращает документ, обратите внимание на его поле Дата. Скорее всего, вы обнаружите его в другом периоде или в «будущем» времени. Для исключения подобных проблем необходимо настроить жесткую синхронизацию времени на всех рабочих станциях с контроллером домена или сервером СУБД.
Посмотрим на ситуацию со стороны СУБД. Процесс записи документа в 1С всегда происходит внутри транзакции. В момент начала транзакции записи СУБД резервирует под документ новый номер (например, №3151). Это гарантирует уникальность номеров при параллельной работе пользователей.
Но что произойдет, если в процессе записи возникнет критическая ошибка или сработает отказ? Рассмотрим механизм скрытого отката транзакции:
Записать(). Платформа начинает транзакцию записи на сервере.ПриЗаписи.Разберем по шагам, как исправить уязвимый код экспорта. Посмотрим на некорректный пример кода, где нет проверки на успешность транзакции:
&НаКлиенте
Процедура ОтправитьВАнализатор(Команда)
Если Модифицированность Тогда
Записать(); // Если здесь произойдет скрытая ошибка, код пойдет дальше!
КонецЕсли;
// Файл уходит во внешнюю систему, даже если документ не сохранился в базе данных
ПередатьДанныеВоВнешнююСистему();
КонецПроцедуры
А теперь проанализируем правильный вариант написания кода с обработкой исключений и проверкой транзакции. Обернем запись в безопасный блок Попытка...Исключение:
&НаКлиенте
Процедура ОтправитьВАнализатор(Команда)
УспешноЗаписан = Истина;
Если Модифицированность Тогда
Попытка
Записать();
Исключение
УспешноЗаписан = Ложь;
ВызватьИсключение "Не удалось записать документ! Отправка данных отменена. Описание ошибки: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если УспешноЗаписан Тогда
// Передача данных выполняется только при гарантированной записи в базу
ПередатьДанныеВоВнешнююСистему();
КонецЕсли;
КонецПроцедуры
Многие разработчики считают, что если они забрали права на удаление у всех ролей в конфигурации, то физически удалить документ никто не сможет. Однако это заблуждение. В 1С существует понятие привилегированного режима.
Если в вашей системе настроены фоновые задания, регламентные обмены (например, с ERP, CRM или бухгалтерией) или подписки на события, они часто выполняются в привилегированных модулях. В этом режиме проверка прав доступа полностью игнорируется. Если в коде стороннего обмена или регламентной очистки «затесался» логический баг, система может программно вызвать метод Удалить() для «пустых» или «первых за день» документов напрямую из базы данных, минуя ограничения ролей пользователей.
---
Если стандартный ЖурналРегистрации поврежден, очищается регламентными скриптами или просто не настроен на полную фиксацию транзакций (например, пишет только ошибки), нам на помощь придут низкоуровневые инструменты СУБД.
Прежде всего, убедимся, что ЖурналРегистрации настроен правильно. Перейдем в Конфигуратор, откроем меню Администрирование -> Настройка журнала регистрации. Установим режим записи событий в положение «Регистрировать ошибки, предупреждения, информацию и примечания». Без этого события успешной записи и изменения объектов просто не будут попадать в логи.
Если база данных работает на MS SQL Server, мы можем настроить аудит изменений на уровне СУБД. Это абсолютно надежный метод, поскольку платформа 1С никак не может обойти триггеры СУБД при выполнении операций INSERT, UPDATE или DELETE.
Рассмотрим подробнее, как реализовать этот механизм:
ПолучитьСтруктуруХраненияБазыДанных()) найдем имя таблицы (например, _Document150).
CREATE TABLE [dbo].[Audit_Doc_Deletions] (
[LogID] [int] IDENTITY(1,1) NOT NULL,
[DocID] [binary](16) NULL,
[ActionType] [varchar](10) NULL,
[HostName] [nvarchar](128) NULL,
[AppName] [nvarchar](128) NULL,
[DBUser] [nvarchar](128) NULL,
[ChangeTime] [datetime] DEFAULT GETDATE()
);
3. Навесим DML-триггер на исходную таблицу нашего документа, который будет срабатывать при удалении или изменении записи:
CREATE TRIGGER [dbo].[Audit_MyDoc_Delete] ON [dbo].[_Document150]
AFTER DELETE, UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[Audit_Doc_Deletions] (DocID, ActionType, HostName, AppName, DBUser)
SELECT
d._IDRRef,
CASE WHEN (SELECT COUNT(*) FROM inserted) = 0 THEN 'DELETE' ELSE 'UPDATE' END,
HOST_NAME(),
APP_NAME(),
SUSER_SNAME()
FROM deleted d;
END
Этот триггер мгновенно запишет в аудиторскую таблицу имя компьютера (HOST_NAME), имя приложения (например, 1cv8.exe или фоновое задание сервера) и системного пользователя ОС, который инициировал удаление или перезапись, даже если действие было совершено под привилегированным режимом 1С.
В редких случаях документы «исчезают» из списков из-за разрушения индексов таблицы базы данных. Физически запись в SQL-таблице присутствует, но из-за повреждения индекса по полю Дата документ не отображается в динамических списках и журналах.
Для исключения этой проблемы запустим процедуру «Тестирование и исправление» (ТиИ):
Используя предложенные методы диагностики, вы гарантированно сможете локализовать проблему «барабашки», исправить некорректно работающий код экспорта и восстановить целостность данных в вашей системе.