2009-04-17 4 views
3

내 MVC 앱에서 다음 코드를 작성하는 데 짜증이납니다.Asp.Net MVC로 자동 트랜잭션을 수행하는 가장 좋은 방법은 무엇입니까?

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

어떻게 든이 DRYer를 만들고 싶습니다.

나는 이것을 위해 몇 가지 다른 옵션을 생각해 보았습니다.

  1. 특정 작업을 트랜잭션으로 표시하는 작업 필터.
  2. 컨트롤러 기본 클래스에서 OnActionExecuting을 재정의하고 모든 작업을 한 번에 처리 할 수 ​​있도록합니다.

이 중 하나를 생각해보십시오. 내가 알아야 할 잡화가 있니? 두 번째 옵션은 교착 상태가 많이 발생하는 좋은 방법 인 것 같습니다.

오 그래, 나는 또한 누군가가 그런 방식으로 거래를 주입하는 몇 가지 트릭을 알고있는 경우에 대비하여 컨트롤러에 deps를 주입하기 위해 StructureMap과 사용자 정의 컨트롤러 팩토리를 사용하고 있습니다.

답변

2

Unit of Work pattern을 사용하여 트랜잭션 관리를 수행 할 수 있습니다. 작업 단 위 패턴의 주요 이점은 거래 전략을 한 곳에서 유지할 수 있다는 것입니다. 또는 여러 전략이있는 경우 몇 군데를 유지할 수 있습니다. 작업 인터페이스의 가장 간단한 장치가 될 수있다 :

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

서로 다른으로 ORMs 또는 저장 프로 시저 또는 하드 코딩 된 SQL에 여러 UnitOfWork에 구현을 만들 수 있습니다. 요청 시작 부분에서 트랜잭션을 시작할 수 있습니다. 트랜잭션은 요청이 끝나면 처리 할 수 ​​있습니다. 처리하기 전에 catch에서 롤백을 사용하여 try-catch 블록에서 커밋을 래핑 할 수 있습니다.

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

이 트랜잭션 시작 전략은 다음과 같습니다 요청에 따라

  • : 하나의 트랜잭션은 전체 요청에 사용됩니다, 이것은 대부분의 경우 가장 좋은 방법입니다.
  • 요청 당 여러 번 : 메서드 당 트랜잭션.
  • 대화 단위 : 장바구니 계산 프로세스의 여러 요청을 중심으로 트랜잭션을 만들 수 있습니다.

당신은 당신의 트랜잭션을 관리 할 수 ​​있습니다

  • 은 Global.asax에있는
  • application_begin 및 EndRequest 이벤트 방법
  • HttpModule의 속성
StructureMap를 사용하는 경우, 당신은 하이브리드 캐싱을 사용할 수 있습니다

작업 단위 구성의 InstanceScope로 StructureMap을 사용하여 작업 단위를 리포지토리에 주입 할 수 있습니다.

1

현재 개발중인 응용 프로그램에서 저의 저장소는 생성자에 주입 된 ISessionProvider에서 NHibernate ISession을 얻습니다. 세션 제공자는 AspNetMvcSessionProvider이며 ISession을 만들고 처음으로 ISessionProvider.OpenSession()이 호출되면 트랜잭션을 시작하여 현재 웹 요청에 ISession을 저장합니다.

OnActionExecuted에서 나는 수동으로 용기 밖으로 ISessionProvider을 끌어 예외가 발생했는지 여부에 따라 그것에 Commit 또는 RollBack 전화 - 물론 아무것도하지 않고, 어떤 세션이 현재 웹 요청에 저장되지 않은 경우.

이것은 유용한 것으로 입증되었으며, 대부분의 경우 응용 프로그램이 다른 판독 트랜잭션을 차단하지 않는 데이터를 읽는 것일뿐입니다. 아직 데이터베이스 교착 상태가 발생하지 않았습니다.

관련 문제