Каков наилучший способ сделать автоматические транзакции с Asp.Net MVC? - PullRequest
3 голосов
/ 17 апреля 2009

Меня раздражает написание следующего кода повсюду в моем приложении MVC.

using(var tx = new TransactionScope()){
   blah...
   tx.Complete()
}

Я бы хотел как-нибудь сделать эту СУШКУ.

Я подумал о нескольких разных вариантах для этого.

  1. Фильтр действий для декларативной маркировки определенных действий как транзакционных.
  2. Переопределите OnActionExecuting в базовом классе Controller и сделайте все действия транзакционными за один выстрел.

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

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

Ответы [ 2 ]

2 голосов
/ 18 апреля 2009

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

public interface IUnitOfWork
{
    void Start();
    void Commit();
    void RollBack();
}

Вы можете создавать различные реализации UnitOfWork для разных ORM, для хранимых процедур или для жестко запрограммированных SQL. Вы можете начать транзакцию в начале запроса. Транзакция может быть размещена в конце запроса. Перед утилизацией вы можете заключить коммит в блок try-catch с откатом в catch.

try
{
    unitOfWork.Commit();
} 
catch
{
     unitOfWork.RollBack();
     throw;
}

Существуют следующие стратегии запуска транзакций:

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

Вы можете управлять своей транзакцией с помощью:

  • атрибуты
  • application_begin и метод endrequest в global.asax
  • HttpModule

При использовании StructureMap вы можете использовать гибридное кэширование как InstanceScope в конфигурации единицы работы. Вы можете добавить единицу работы в репозитории с помощью StructureMap.

1 голос
/ 18 апреля 2009

В приложении, которое я сейчас разрабатываю, мои репозитории получают NHibernate ISession от ISessionProvider, который вводится в конструктор. Поставщик сеанса - AspNetMvcSessionProvider, который создаст ISession и начнет транзакцию при первом вызове ISessionProvider.OpenSession(), сохраняя ISession в текущем веб-запросе.

В OnActionExecuted я вручную вытаскиваю ISessionProvider из своего контейнера и вызываю Commit или RollBack, в зависимости от того, было ли сгенерировано исключение - ничего не делая, конечно, если сессия в данный момент не сохранена в веб-запросе.

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

...