2010-01-26 1 views
7

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

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

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

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

благодаря

ответ

6

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

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

спасибо за ответ. Что вы думаете по поводу обработки SQLExceptions? Для ошибок, возникающих в sproc, вы поймаете их в DAL и выбросите пользовательскую ошибку здесь или какую-нибудь альтернативу? – Nick

+1

В моем текущем DAL (больше DA * tool *, который я передаю в свои бизнес-объекты, которые также являются полуфабрикатными объектами DAL) Я поймаю и обработаю несколько конкретных ошибок автоматически (например, ошибка жертвы тупика № 1205. Если Я вижу это, я попробую еще раз.), Но пусть большинство ошибок просачиваются. Иногда бизнес-объект может делать что-то умное с этой ошибкой; если я не позволю ему просачиваться. В моем DAL я скоро автоматически зарегистрирую ошибку и текст и параметры команды sql автоматически. Я счел полезным добавить текст sql в сообщение об ошибке, но это проблема безопасности. –

+0

Только ошибки ловушки в sprocs/udf, если вы можете (** A **) восстановить/отреагировать/возможно, или, если (** B **), вы можете улучшить информацию об ошибках, которая просачивается вверх. Таким образом, по умолчанию в sproc/udf нет обработки ошибок, но иногда вы иногда добавляете к ним сообщение об ошибке. –

1

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

-Krip

+0

Приветствия для комментария крип , будет помнить об этом в таких ситуациях. – Nick

1

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

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

В вашем уровне данных, можно использовать стандартные шаблоны (например, using statement для IDisposables, таких как SqlConnection), исключения документов вы знаете может произойти (не сделать это для памяти или других редких случаев), а затем пусть они перетекают в стек вызовов, когда они это делают. В большинстве случаев вы можете захотеть поймать эти исключения и обернуть их в одном типе исключений, в ситуациях, когда MANY-исключения могут обрабатываться вызывающими.

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

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

+0

Так что его дожидаться сбора мусора, чтобы закрыть соединение, используя оператор using? – Nick

+1

Нет, вы должны немедленно закрыть соединение (a) или (b) в блоке finally или использовать синтаксис/шаблон использования, чтобы это произошло автоматически. Я расскажу об этом. , , –

+0

@nick проверить ссылку в моем ответе для инструкции 'using'. – Will

0

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

Application Architecture Guide

Web Applications Guides

+0

спасибо за ссылки, они действительно действительно полезны. – Nick