По какому принципу формируется поле Version у документов 1С в SQL и как его расшифровать?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Природа поля Version: мифы и реальность

Рассмотрим ситуацию: при анализе таблицы документа в SQL мы видим колонку Version с типом данных timestamp (в новых версиях SQL Server он называется rowversion). Значения в нем выглядят как шестнадцатеричные числа, например, 0x0000000000263CED. Проанализируем основные заблуждения, связанные с этим полем:

  1. Это Unix-время. Часто предполагается, что это количество секунд или миллисекунд, прошедших с 1 января 1970 года.
  2. Это упакованная дата 1С. Существует мнение, что 1С записывает туда момент сохранения документа в своем внутреннем формате.

На самом деле, тип данных rowversion в MS SQL Server никак не связан с системными часами. Это просто 8-байтовое двоичное число, которое увеличивается внутри конкретной базы данных при каждой операции вставки или обновления строки. Выясним, как именно это работает.

Механизм работы счетчика rowversion

Разберем по шагам, что происходит в базе данных, когда мы записываем документ:

  1. В каждой базе данных SQL Server есть глобальная переменная — счетчик текущей версии базы (@@DBTS).
  2. Когда любая транзакция изменяет строку в любой таблице, где есть колонка типа rowversion, этот счетчик увеличивается на единицу.
  3. Новое значение счетчика записывается в поле Version изменяемой строки.

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

Зачем 1С использует это поле? Оптимистическая блокировка

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

  1. При чтении данных из SQL в память компьютера пользователя, 1С считывает текущее значение Version.
  2. Когда пользователь нажимает "Записать", 1С формирует SQL-запрос, в котором проверяет: совпадает ли версия в базе данных с той версией, которую мы прочитали изначально.
  3. Если за время редактирования кто-то другой успел изменить документ, значение Version в базе увеличилось. Проверка не пройдет, и 1С выдаст ошибку: «Объект изменен или удален другим пользователем».

Можно ли конвертировать Version в Дату?

Как мы уже выяснили, прямой математической связи между числом 0x0000000000263CED и временем записи не существует. Поле Version не хранит время. Единственное, что можно сделать — это сравнивать версии между собой, чтобы понять, какой объект был изменен позже.

Тем не менее, в 1С иногда возникает необходимость работать с реальными Unix Timestamp (метками времени в секундах от 1970 года), например, при интеграции со сторонними веб-сервисами. Чтобы не путать их с системным полем Version, рассмотрим пример функций для преобразования обычной даты 1С в Unix-timestamp и обратно:


Функция ДатуВTimestamp(пДата = Неопределено) Экспорт
    Если пДата = Неопределено Тогда
        пДата = ТекущаяДата();
    КонецЕсли;
    
    // Вычисляем разницу в секундах между датой и началом эпохи Unix
    Возврат Формат(Число(пДата - Дата("19700101")), "ЧН=0; ЧГ=0");
КонецФункции

Функция TimestampВДату(пДатаТС) Экспорт
    Попытка
        // Прибавляем количество секунд к дате начала эпохи
        Возврат Дата("19700101") + ?(ТипЗнч(пДатаТС) = Тип("Строка"), Число(пДатаТС), пДатаТС);
    Исключение
        Возврат Неопределено;
    КонецПопытки;
КонецФункции

Важно: Эти функции полезны для работы с API (например, REST), но они не помогут расшифровать поле _Version из SQL-таблицы 1С.

Использование Version в платформе 8.3

В современных версиях платформы (8.3.x и выше) поле Version нашло дополнительные применения. Проанализируем их:

Подведем итоги

Разберем ключевые выводы нашего анализа:

  1. Поле Version — это технический счетчик SQL Server типа rowversion.
  2. Оно уникально в пределах всей базы данных (не только одной таблицы).
  3. Оно не содержит в себе информацию о дате и времени.
  4. Его главная задача — обеспечить оптимистическую блокировку и целостность данных при одновременной работе пользователей.
  5. В языке 1С это поле напрямую недоступно через объектную модель (через точку), но его можно получить с помощью прямого SQL-запроса или увидеть в инструментах отладки при работе с внешними источниками данных.

Понимание работы этого механизма помогает лучше разобраться в том, как 1С взаимодействует с СУБД и почему возникают ошибки конкурентного доступа к данным. Помните, что для отслеживания времени изменений объектов в 1С следует использовать стандартный механизм Версионирования объектов (История данных), который сохраняет реальную дату и время каждого изменения в отдельных служебных таблицах.

← На главную