Почему в 1С документы создаются будущим временем и как это исправить?

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

Часто разработчики и пользователи сталкиваются с загадочной ситуацией: при создании или записи документа его время автоматически сдвигается в будущее на несколько минут (а иногда часов или дней). Например, в обработчике ПередЗаписью время документа еще совпадает с текущим (допустим, 18:01), а уже в процедуре ПриЗаписи или после проведения время меняется на 18:06. При этом системное время на сервере 1С и сервере СУБД абсолютно корректное.

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

Механизм оперативного проведения и отметки времени

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

Чтобы обеспечить уникальность времени, платформа выдает каждому новому документу так называемую оперативную отметку времени. Если мы вызовем функцию ПолучитьОперативнуюОтметкуВремени(), то можем увидеть, что она выдает время, превышающее текущее.

Расчет оперативной отметки происходит по следующему правилу: платформа берет максимальное значение из двух величин:

  1. Текущее физическое системное время сервера 1С.
  2. Последняя выданная оперативная отметка плюс одна секунда.

Из-за этого алгоритма возникает эффект «залипания» времени. Платформа кэширует последнее выданное значение в оперативной памяти сервера (в рабочем процессе). Если по какой-то причине отметка времени сдвинулась в будущее, она уже не вернется назад автоматически, пока реальное время не «догонит» этот сдвиг.

Причины сдвига времени в будущее

Проанализируем ситуации, которые приводят к смещению счетчика времени:

1. Массовое оперативное проведение в цикле (регламентные задания)
Это самая частая причина, которая и наблюдалась в исходной проблеме. Если в базе работает регламентное задание, обработка загрузки или любой другой алгоритм, массово создающий и проводящий документы (сотни или тысячи в секунду), платформе приходится на каждый из них накидывать по одной секунде. Если обработка создает 300 документов за одну физическую секунду, время последнего документа убежит на 5 минут в будущее.

2. Ошибки с отмененными транзакциями
Сдвиг может происходить еще быстрее, если регламентное задание пытается оперативно провести документы, но получает отказ (например, не хватает остатков). Отметка времени запрашивается, сдвигается на секунду вперед, а затем транзакция отменяется. Документа в базе нет, но счетчик в памяти сервера уже сдвинут.

3. Ручное вмешательство
Пользователь с полными правами случайно или намеренно создал документ завтрашним днем и провел его оперативно. Платформа запомнила эту будущую отметку, и теперь все новые документы от всех пользователей будут выстраиваться в очередь после этой «завтрашней» даты.

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

Способы решения проблемы

Рассмотрим, как правильно бороться с этим явлением и не допускать его в будущем.

Исправление программного кода (Профилактика)
При программном массовом создании и проведении документов в фоне, обменах или регламентных заданиях необходимо использовать неоперативное проведение. В этом режиме платформа не запрашивает новую оперативную отметку и не смещает кэш. Документ просто записывается тем временем, которое установлено в его реквизите.


ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);

Также, если вы генерируете технические или исторические документы, где проведение не требуется или логика позволяет обойти проверки, используйте режим загрузки:


ДокументОбъект.ОбменДанными.Загрузка = Истина;
ДокументОбъект.Записать();

Сброс зависшей отметки времени (Лечение)
Если смещение уже произошло, база не «излечится» сама, пока не наступит закэшированное будущее. Чтобы сбросить счетчик немедленно, выполните следующие шаги:

  1. Найдите в базе все документы, дата которых больше текущего физического времени. Для этого можно воспользоваться обычным журналом документов или написать простой запрос.
  2. Перенесите найденные документы в прошлое (на актуальное или прошедшее время), распроведите их или удалите, если они были созданы ошибочно.
  3. Обязательный шаг: Перезапустите службу сервера 1С (процесс rphost). Так как последняя отметка времени хранится в оперативной памяти конкретного рабочего процесса, без перезапуска сервера платформа продолжит опираться на ошибочное значение, даже если документов из будущего в базе больше нет.

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

← На главную