2014-12-20 1 views
1

새로운 웹 API 응용 프로그램을 시작할 예정이며 트랜잭션 처리 방법을 잘 모르겠습니다. 예외).오류 (EF6, 웹 API2, NInject)에 대한 자동 커밋/롤백을 사용하여 전체 요청 기간 동안 명시적인 트랜잭션

내 개인적인 목표는 요청 당 하나의 데이터베이스 연결을 가지며 전체 내용을 명시 적 트랜잭션으로 래핑하도록하는 것입니다. 저장 프로 시저를 실행할 것이므로 명시 적 트랜잭션이 필요하며 내 응용 프로그램에서 예외를 throw해야하는 경우 결과를 롤백해야합니다.

내 계획은 이전에 MVC 응용 프로그램에서 사용한 접근법을 재사용하는 것이 었습니다. 거친 말로하면 ninject를 사용하여 requestscope에 데이터베이스 컨텍스트를 바인딩 한 다음 ondeactivation 이벤트에서 롤백/커밋을 처리하는 것이 었습니다.

컨트롤러에 두 가지 방법이 있다고 가정 해 봅니다.

public class MyController : ApiController { 

    public MyController(IRepo repo) { 
    } 
    } 


    public string SimpleAddElement() { 
    _repo.Add(new MyModel()); 
    } 

    public string ThisCouldBlowUp() { 
    // read from context 
    var foo = _repo.ReadFromDB(); 

    // execute stored prodecure which changes some content 
    var res = _repo.StoredProcOperation(); 

    // throw an exception due to bug/failsafe condition 
    if (res == 42) 
     throw Exception("Argh, an error occured"); 
    } 
} 

내 REPO 골격 여기에서

public class Repo : IRepo { 
    public Repo(IMyDbContext context) { 
    } 
} 

, 내 계획은 단순히

kernel.Bind<IRepo>().To<Repo>(); 

를 사용하여 저장소를 결합하여 사용 요청에 따라 단일 데이터베이스 컨텍스트를 제공하는 것이 었습니다

kernel.bind<IMyDbContext>().To<CreateCtx>() 
     .InRequestScope() 
     .OnDeactivate(FinalizeTransaction); 

private IMyDbContext CreateCtx(IMyDbContext ctx) { 
    var ctx = new DbContext(); 
    ctx.Database.BeginTransaction(); 
} 

private void FinalizeTransaction(IMyDbContext ctx) { 
    if (true /* no errors logged on current HttpRequest.AllErrors */) 
    ctx.Commit(); 
    else 
    ctx.Rollback();  
} 

지금 , 내 브라우저에서 SimpleAddElement를 호출하면 FinalizeTransaction이 호출되지 않습니다. 그래서 WebAPI 파이프 라인과 관련하여 뭔가 잘못되었거나 누락되었습니다.

그렇다면 트랜잭션 "단일 DB 세션 요청 "- 모듈? 모범 사례는 무엇입니까? 가능한 경우 ASP vNext도 지원하는 솔루션을 원합니다.

"ondeactivation"처리기를 삭제하고 Endrequest에서 커밋하고 Error에서 롤백하는 HTTP 모듈을 구현할 수있는 잠재적 인 해결책이 있다고 생각합니다. 그게 내가 좋아하지 않는 것에 관한 것입니다.

+0

사용중인 NuGet 패키지 Ninject.Web.Common의 버전을 알려주십시오. – Frank

답변

0

코드에 추상화가 없습니다. 컨트롤러 내부에서 비즈니스 논리를 실행하는데 잘못된 위치입니다. 이 논리를 비즈니스 계층에 추출하여 추상화 뒤에 숨기면 트랜잭션 내에서 모든 비즈니스 계층 작업을 래핑하는 것이 쉽습니다. 이에 대한 예제는 this article을 참조하십시오.

+0

코드는 단순화되었습니다. 나는 컨트롤러와 리포지토리 사이에 서비스 레이어를 가지고 있지만, 그 결과는 DB 작업이 결과적으로 중요하다는 것입니다. 그 기사를 보도록하겠습니다. – Thomas