Как и где обрабатывать исключения в трехуровневом веб-приложении? В частности, исключения из базы данных SQL - PullRequest
7 голосов
/ 26 января 2010

Я создаю стандартное 3-уровневое веб-приложение ASP.NET, но я пытаюсь понять, где делать определенные вещи, в частности обработку исключений.

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

На своем уровне данных я подключаюсь к SQL Server и выполняю некоторые действия. Я знаю, что мне нужно ловить исключения, которые могут возникнуть в результате, но я не уверен, где это сделать.

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

спасибо

Ответы [ 4 ]

6 голосов
/ 26 января 2010

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

  • Никогда не скрывайте трассировку стека; никогда не используйте "Rethrow", если только в целях безопасности вы не хотите скрыть то, что произошло.
  • Не думайте, что вам нужна обработка ошибок везде. По умолчанию, на ваших нижних уровнях позволить фактической ошибке просачиваться до верхнего уровня неплохо. Пользовательский интерфейс / контроллер - это место, где вы должны решить, как реагировать на что-то не так.
  • В каждый момент, как и вы сами, что именно вы хотите случиться, если что-то пойдет не так. Зачастую вы не сможете придумать ничего лучше, чем просто позволить ему подняться на верхний уровень или даже на клиентский компьютер. (хотя в рабочей очереди подробных отчетов.) Если это так, просто отпустите.
  • Убедитесь, что вы избавляетесь от неуправляемых ресурсов (всего, что реализует IDisposable.) Ваш доступ к данным является отличным примером. Либо ( A ) вызовите .Dispose () для вашего (особенно) соединения, команды, устройства чтения данных и т. Д. В блоке Наконец , либо ( B ) используйте Использование синтаксиса / шаблона , который обеспечивает правильную утилизацию.
  • Ищите места, где возможны ошибки и где вы можете искать определенные ошибки, реагировать (повторяя попытку, ожидая повторную попытку, пытаясь выполнить это действие другим способом и т. Д.), А затем надеясь на успех. Большая часть вашей обработки исключений состоит в том, чтобы добиться успеха, а не просто сообщать о сбоях.
  • На уровне данных вы должны подумать, что делать, если что-то пойдет не так в середине многоэтапного процесса. Вы можете позволить фактической ошибке просачиваться, но этот слой должен обрабатывать исправление ошибок после ошибки. Иногда вам захочется использовать транзакции.
  • В асинхронной ситуации (либо (A.) из-за нескольких потоков, либо (B.), потому что бизнес-логика - это процессы, выполняемые отдельно на «машинах задач» и т. Д. И выполняемые позже), в частности, вам необходимо иметь план для ошибки логирования.
  • Я бы предпочел увидеть «код обработки ошибок» в 25% вашего приложения, чем в 100%. 100% означает, что вы, вероятно, хотели, чтобы он выглядел и чувствовал, что у вас есть обработка ошибок. 25% означает, что вы потратили время на обработку исключений там, где они действительно должны быть обработаны.
1 голос
/ 26 января 2010

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

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

На вашем уровне данных вы будете использовать стандартные шаблоны (например, оператор using для таких идентификаторов, как SqlConnection), могут возникнуть исключения из документов, которые вы знаете (не не делать это из-за нехватки памяти или других редких случаев), а затем позволить им течь вверх по стеку вызовов, когда они это делают. Самое большее, вы можете захотеть перехватить эти исключения и обернуть их в один тип исключений, в тех случаях, когда МНОГИЕ исключения могут быть обработаны вызывающими.

Если вам нужно «очистить» вещи перед тем, как пропустить исключения, вы всегда можете использовать finally блок для очистки. Вам не нужно catch, чтобы использовать блок finally.

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

1 голос
/ 26 января 2010

Просто побочный момент, который может направить ваше мышление: если у вас есть какой-либо тип тома, который может привести к проблемам параллелизма (взаимоблокировки), вы захотите, чтобы ваше приложение обнаружило эту конкретную ошибку SQL и повторило операцию (например, транзакцию). Это требует какой-то обработки исключений на уровне данных или бизнес-уровня.

-Krip

0 голосов
/ 26 января 2010

Это не конкретный ответ на ваш вопрос, но если вас интересуют передовые практики, я бы посмотрел шаблоны и практики Microsoft:

Руководство по архитектуре приложений

Руководства по веб-приложениям

...