В настоящее время я использую шаблон Open Session in View в приложении ASP.NET WebForms (немного адаптированный из Billy McCafferty's http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx).. Чтобы просто изложить, что здесь происходит:
- Открыть транзакцию NHibernate в начале запроса
- Фиксация в конце запроса (откат при любых ошибках)
Я обычно обрабатываю любые исключительные ошибки базы данных, фиксируя их в Application_Error (где я регистрирую, перенаправляю на страницу общих ошибок и т. Д.) Следующим образом:
...
if (Context != null && Context.IsCustomErrorEnabled)
{
Server.Transfer(ErrorPageLocation, false);
}
else
{
log.Error("Unhandled Exception trapped in Global.asax", exception);
}
но с NHibernate, к тому времени, когда я получаю какие-либо ошибки NHibernate / базы данных, уже слишком поздно в запросе делать мой обычный Server.Transfer (очевидно, что передача не случится так поздно в запросе) перенаправление ошибок (хотя ведение журнала все еще имеет место). В качестве очень быстрого исправления я сделал следующее в своем пользовательском HttpModule HttpApplication Context EndRequest:
try
{
// Commits any open transaction and throws after rolling back any HibernateException and closing session.
NHibernateSessionManager.Instance.CommitTransaction();
}
catch (HibernateException)
{
HttpContext.Current.Response.Redirect(ERROR_PAGE_LOCATION);
}
finally
{
NHibernateSessionManager.Instance.CloseSession();
}
... но это пахнет не только потому, что я сейчас ссылаюсь на NHibernate в моей сети, но в основном потому, что я уверен, что должен быть лучший способ. Что было бы лучшим способом справиться с перенаправлением пользователя на общую страницу ошибок в случае ошибки базы данных / NHibernate, где, как и любые исключения, выброшенные в этот момент, выкидываются слишком поздно в процессе, чтобы обрабатываться дальше в запросе с Server.Transfer в Global.asax.cs Application_Error? Если сделать еще один шаг вперед, то с веб-сервисами это становится еще сложнее, поскольку вышеупомянутый хак, очевидно, не имеет никакого эффекта (и никакие исключения не генерируются для обработки на принимающей стороне - в моем случае, чаще всего при вызовах ajax на стороне клиента).
Пожалуйста, скажите мне, что я упускаю что-то очевидное (обычно очевидное поражает меня сразу после того, как я нажимаю "Отправить" на вопросы, подобные этим) *