Ошибки из-за неправильного обращения и обратная связь при выполнении объемных операций в многоярусной архитектуре

Нет, хорошая статья находится здесь в Mozila Wiki.

я продолжил бы использовать недопустимое attribute. Я думаю, что это - то, где прагматизм должен выиграть проверку.

12
задан Adam Batkin 27 August 2009 в 18:24
поделиться

8 ответов

Насколько я понимаю, у вас есть ситуация, когда некоторые запросы могут проходить, а некоторые терпеть неудачу. Я не уверен, куда вы хотите, чтобы ошибка вернулась, но у вас может быть одно из следующего (или вариант, или комбинация):

  • Список ошибок и затронутых объектов домена. Объект базового домена или что-то с постоянным идентификатором может быть полезно для повторного использования. Например, набор ошибок, относящихся к объектам домена.
  • Вы можете ввести (AOP, DI) в объект Person какой-нибудь объект / сообщение об ошибке. Например, if (person. Errors) {...}
  • Вы можете заключить коллекцию Person в сообщение с заголовком, телом и информацией об ошибке
  • Все объекты вашего домена могут включать коллекцию ошибок, доступную через интерфейс; или Person поддерживает интерфейс IHasErrors. Вы можете сделать это универсальным и использовать базовый объект Error, поддерживающий предупреждения, проверку и всевозможные вещи.

Если вы работаете в подлинной многоуровневой (а не многоуровневой) системе, то у вас может быть архитектура на основе сообщений, которая могла бы легко приспособить какой-то общий механизм ошибок / предупреждений / проверки. Системы SOA / Ajax поддаются этому.

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

1
ответ дан 2 December 2019 в 21:03
поделиться

Я бы предпочел вернуть набор пользовательских- внесены объекты ошибок, идентифицирующие объект, на который влияет ошибка, код ошибки и описание. Таким образом, ошибки можно будет попытаться исправить или отобразить для пользователя.

1
ответ дан 2 December 2019 в 21:03
поделиться

Я думаю, что вы действительно злоупотребляете исключениями, если думаете в этих терминах!

Это вполне нормально возвращать значения, которые означают отказ, а не генерировать исключение. Часто лучше. Исключения лучше всего использовать, когда вы не можете восстановить на том уровне абстракции, на котором вы находитесь, но вы не должны использовать их в качестве основного средства управления потоком, иначе ваши программы будут очень трудно читать.

Веб-служба делает это. не возвращает исключения, он возвращает коды возврата и сообщения. Я бы сохранил какое-нибудь полезное представление, которое представляет возвращаемую информацию,

1
ответ дан 2 December 2019 в 21:03
поделиться

Я бы, вероятно, вернул карту результатов типа Map > из моей getLotteryNumbers > service.

Затем я бы перебрал карту и использовал Future.get () , чтобы получить либо номер лотереи, либо сгенерированное исключение.

В некоторых из моих сервисов я хотел бы реализовать все вызовы как вызовы одного элемента, а затем в моем сервисе есть логика, позволяющая группировать их и обрабатывать как группу. Пакетная обработка реализуется с использованием LinkedBlockingQueue и потока опроса.

В этом сценарии я возвращаю Future , который ожидает, пока результаты пакета будут доступны, используя ] Обратный отсчет .

Взгляните на Java Concurrency на практике, чтобы увидеть, как все эти компоненты могут работать вместе http://jcip.net/

0
ответ дан 2 December 2019 в 21:03
поделиться

Я бы посмотрел на DTO для такого рода задач. DTO может также включать информацию о том, было ли сохранение успешным или нет, и другие виды «метаданных».

0
ответ дан 2 December 2019 в 21:03
поделиться

В этом вопросе подчеркиваются важные различия между подходящим использованием обработки исключений, транзакций, и идея «компенсации» рабочего процесса , к которой пытается добраться спрашивающий, если правильно заявить:

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

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

Транзакции с данными изначально моделировались на основе двойной записи - единого кредита и соответствующий дебет должны были регистрироваться вместе или не регистрироваться вовсе. По мере того, как транзакции становятся больше, чем это, их становится все труднее правильно реализовать и все труднее справляться с ошибками. Когда вы начинаете переносить идею единственной транзакции через границы системы, вы, скорее всего, ошибаетесь. Это можно сделать, но требует сложных координаторов транзакций с высокой задержкой. В определенном масштабе транзакции являются неправильным мышлением, и компенсация начинает иметь гораздо больший смысл.

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

Например, если вы заказываете книгу на Amazon, они, вероятно, не «блокируют» записывайте, пока она находится в корзине, или даже используйте строгие транзакции, чтобы определить, есть ли книга в наличии, когда заказ будет подтвержден. Они все равно продадут его вам и отправят, когда смогут. Если им не удалось получить его на складе в течение нескольких недель, они, вероятно, отправят вам электронное письмо с сообщением, что они пытаются удовлетворить ваши потребности, и вы можете продолжать ждать, пока они появятся на складе, или вы можете отменить свой заказ. Это называется компенсацией и необходимо во многих реальных бизнес-процессах.

Наконец, в этом нет ничего исключительного . Ожидайте, что это может произойти, и используйте обычный поток управления. Вы не должны использовать здесь особенности обработки исключений вашего языка ( хорошие правила, когда генерировать исключение ). Также вам не следует полагаться на механизмы, специфичные для инструмента (WCF?), Для просмотра или обработки исключений, которые происходят в реализации службы. Сообщение об ошибках должно быть нормальной частью вашего контракта на данные (контракты на сбой).

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

Резюме:

  • Ваша проблема переросла концепцию транзакции -> изучите компенсацию рабочего процесса.

Удачи -

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

Резюме:

  • Ваша проблема переросла концепцию транзакции -> изучите компенсацию рабочего процесса.

Удачи -

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

Резюме:

  • Ваша проблема переросла концепцию транзакции -> изучите компенсацию рабочего процесса.

Удачи -

10
ответ дан 2 December 2019 в 21:03
поделиться

В идеале вызов вашей веб-службы должен быть таким:

List<Person> selectedPeople = ... //fetch list of people
callLotteryNumberWebService(selectedPeople.ToArray );

Выполнение вызова веб-службы для каждого человека обходится дорого. На стороне сервера вам нужно перебрать список и выполнить операцию. Код на стороне сервера может вызывать 2 исключения: BulkOperationFailedException - если есть фатальная ошибка из-за неработающей базы данных или отсутствия файла конфигурации. Дальнейшая обработка невозможна. BulkOperationException - содержит массив исключений, относящихся к человеку. Вы можете сохранить некоторый идентификатор для уникальной ссылки на каждый объект. Ваш код будет иметь следующий вид:

List<Person> selectedPeople = ... // fetch list of people 

try{
    callLotteryNumberWebService(selectedPeople.ToArray);
}catch  (BulkOperationFailedException e) {
    SOP("Some config file missing/db down.No person records processed")
}catch(BulkOperationException e)  {
    UserDefinedExceptions us =  e.getExceptions()
    foreach(exception ein us)   {
        // read unique id to find which person object failed
    }
}

construct msg based on which personobject succeeded and which failed

Операция считается успешной, если не генерируются исключения. У вас могут быть собственные коды ошибок для сбоев вместо использования исключений, определенных пользователем. Создание BulkOperationException на стороне сервера непросто. Во-вторых, вам нужно классифицировать ошибки, возникающие на стороне сервера, на BulkOperationFailedException и BulkOperationException. Так я поступил в одном из моих проектов

1
ответ дан 2 December 2019 в 21:03
поделиться

Экземпляр перечисления может иметь любой присваиваемый базовый тип (например, int.MinValue через int.MaxValue для любого обычного перечисления). Вы можете получить список значений с именем , вызвав Enum.GetNames и Enum.GetValues ​​.

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

0
ответ дан 2 December 2019 в 21:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: