Обработка системных ошибок
Когда обновлённый набор данных отправлен на сервер для применения к базе данных, на сервере могут возникать системные ошибки. Поэтому необходим способ поиска и анализа этих ошибок, когда набор данных возвращается клиенту. Система устанавливает атрибут ERROR если обнаружит ошибку во время выполнения операций SAVE-ROW-CHANGES () или FILL.
Атрибут ERROR устанавливается на трёх уровнях:
- Для конкретного буфера (строки) временной таблицы, где обнаружена ошибка. Устанавливается для before-table и after-table.
- Для конкретной временной таблицы, в которой обнаружена ошибка. Устанавливается для before-table и after-table.
- Для всего набора данных.
На стороне клиента необходимо написать код для проверки атрибута ERROR на этих уровнях чтобы определить строку, в которой произошла ошибка. Сначала проверяется уровень набора данных. Если ошибка произошла, то затем проверяется каждая таблица after-table чтобы определить в какой временной таблице произошла ошибка. Затем выполняется перебор строк after-table или before-table чтобы определить конкретную строку с ошибкой.
Чтобы позволить системе установить атрибут ERROR на сервере, необходимо использовать синтаксис NO-ERROR при вызове методов SAVE-ROW-CHANGES или FILL. В противном случае если ошибка возникнет, то процедура на стороне сервера будет прервана и атрибут ERROR установлен не будет.
Управление размером транзакции на сервере
При использовании наборов данных применяются такие же требования к управлению транзакциями, которые используются для любого бизнес-приложения.
Старайтесь ограничивать размер транзакций, включая в них только самые важные наборы записей. Тем самым контролируя размер набора изменений, на который окажет влияния возникшая ошибка. Например, если мы создадим очень маленькую транзакцию, то любые ошибки, возникшие во время обработки этой транзакции, повлияют только на этот небольшой набор изменений. Если же транзакция будет очень большой, то единственная ошибка приведёт к откату очень большого набора изменений, основная часть которых в действительности не является причиной возникновения ошибки.
Тем не менее, всё это должно быть сопоставимо с потребностями бизнеса. Возможно, что правильные изменения тоже потребуется откатить, так как чтобы транзакция была признана успешной, все её изменения должны быть успешными.
Ниже приведён пример того, что нужно добавить к серверному коду, чтобы включить атрибут ERROR для системных ошибок. Обратите внимание, что вызов метода SAVE-ROW-CHANGE () дополнен параметром NO-ERROR. Если возникнет ошибка во время применения изменений к базе данных, то AVM автоматически установит для соответствующих строк таблиц before и after атрибут ERROR в значение TRUE. Кроме того, в самих таблицах before и after, а также в наборе данных атрибуту ERROR также будет установлено значение TRUE.
. . . hQuery:GET-FIRST. DO WHILE hBeforeBuffer:AVAILABLE: hBeforeBuffer:SAVE-ROW-CHANGES() NO-ERROR. hQuery:GET-NEXT. END. . . .
Обнаружение атрибута ERROR на клиенте
Представим, что метод SAVE-ROW-CHANGES вызывается на сервере для before-таблицы Order и её дочерней before-таблицы OrderLine. Во время выполнения метода происходит ошибка, которая устанавливается для набора данных, соответствующей before-таблицы и строки. Например из-за того, что значение из before-таблицы не соответствует тому, что находится в базе данных, потому что другой клиент изменил эту же запись ранее, в результате выполнение SAVE-ROW-CHANGES завершается с установкой атрибута ERROR.
На стороне клиента мы должны проверить строки временной таблицы. Мы должны выполнить следующие действия для обработки ошибок в возвращённом наборе данных изменений:
- Проверить наличие ошибок на уровне всего набора данных. Если их нет, то завершаемся, так как нет смысла далее искать временные таблицы с ошибками.
- Если ошибки есть, то проверяем каждую временную таблицу.
- Если нашлись таблицы с ошибками, погружаемся на уровень строк и проверяем каждую.
Чтобы определить, произошла ли ошибка в наборе данных в целом, используется атрибут ERROR хэндла набора данных следующим образом:
IF hChangeDataSet:ERROR THEN DO: /* Perform ERROR handling */ END.
Чтобы определить, произошла ли ошибка во временной таблице набора данных, используется атрибут ERROR хэндла before-таблицы:
IF hBuffer:TABLE-HANDLE:ERROR THEN DO: /* Perform ERROR handling */ END.
Чтобы определить запись, в которой произошла ошибка, используется атрибут ERROR хэндла буфера временной таблицы:
IF hBuffer:ERROR THEN DO: /* Perform ERROR handling */ END.
Как строки с ошибками объединяются обратно в набор данных клиента
Напомним, что на стороне клиента мы вызываем метод MERGE-CHANGES () чтобы объединить возвращённый с сервера набор данных изменений с набором данных клиента. Если в какой-либо строке атрибут ERROR будет иметь значение TRUE, то строка не будет записана обратно в клиентский набор данных.
Метод MERGE-CHANGES () обрабатывает строки с атрибутом ERROR следующим образом:
- Если строка была создана в наборе данных клиента, то она удаляется.
- Если строка была удалена, то добавляется обратно.
- Если строка была изменена, произойдёт откат изменений.