Допустим на форме документа команда, которая вместе с записью (или проведением) документа создает определенный связанный объект содержащие ссылку на текущий документ, а ссылка на подчиненный объект сохраняется в текущем документе.
Причем в случае ошибки при записи (или проведении) документа отменяется также создание подчиненного объекта.
Кроме того при ошибке создания подчиненного объекта также отменяется запись (или проведение) текущего документа.
При какой-либо ошибке выводится сообщение об ошибке, которое позволяет поправить некоторые настройки создания подчиненного объекта и провести текущий документ еще раз.
Пример реализации алгоритма с обманчивым сообщением об ошибке:
- Команда вызывает запись документа из серверного контекста формы для получения ссылки на документ.
- Полученная ссылка передается в процедуру модуля менеджера документа или общего модуля для создания связанного объекта.
- Выполняется сохранение ссылки подчиненного объекта в текущем документе и запись текущего документа.
- Запись документа и создание подчиненного объекта производится в транзакции с попыткой, с отменой транзакции при ошибке и выводом сообщения об ошибке.
Через некоторое время нормальной работы в панике звонит пользователь и сообщет, что заведенный непосильным трудом большой документ не сохраняется и при этом постоянно выдается ошибка «Данные были изменены или удалены другим пользователем».
Опытный программист понимает, что документ новый и создан в транзакции, поэтому другие пользователи его видеть не могут.
Поэтому единственная возможность такой ошибки это, когда при определенных условиях где-то при формировании подчиненного объекта по переданной ссылке был получен объект текущего документа и записан.
Перелопачивается код создания подчиненного объекта, но получения объекта по ссылке и его записи нет...
Программист пробует воспроизвести ошибку на тех же данных, но она не появляется...
Вот, что проиходит.
Пользователь при заведении документа столкнулся с ошибкой при формирования подчиненного объекта, получил сообщение об ошибке, поправил настройки создания подчиненного объекта и пробует еще раз записать (или провести) текущий документ.
На первый взгляд ошибки уже быть не должно, ведь была попытка и исключение, транзакция отменена и можно пробовать еще несколько раз.
Расмотрим внимательнее версии объекта текущего документа и его ссылки после ошибки.
До отмены транзакции и объект и ссылка записанного в пределах транзакции документа содержат одинаковую версию.
После отмены транзакции версия ссылки очищается, а версия объекта не очищается!
Поэтому при любой попытке последующий записи вызывается ошибка «Данные были изменены или удалены другим пользователем», а значит данные текущего документа уже никогда не удастся сохранить в базе.
Пытливый читатель подумает, а что происходит с версией объекта при отмене транзакции, если документ не открыт, а создан программно.
В последнем случае программной работы сообщение об ошибке будет: «Документ не выбран».
Исправляется ошибка предварительным получением ссылки, чтобы запись текущего документа в форме производилась в самом конце.
После этого будет повторятся первоначальная ошибка и не затеряется среди множества ошибок «Данные были изменены или удалены другим пользователем».
Надеюсь статья, кому-нибудь поможет отловить настоящую причину ошибки в запутанной конфигурации написанной не очень правильно.
К статье приложена выгрузка тестовой конфигурации, в которой есть документ с кнопками для воспроизведения обманчивой ошибки, исправления ошибки, честной ошибки и программной записи после отмены транзакции.