1

try-catch 블록 (catch/handle)이있는 저장소를 ASP.NET MVC 응용 프로그램의 해당 컨트롤러 내부로 래핑해야합니까, 아니면 저장소 구현 내부에서 수행해야합니까?StaleObjectStateException을 처리 할 곳

또한 예외를 처리하고 사용자에게 알리십시오. 내가 아는 한 롤백은 의도 된 것이 아닙니까?

감사합니다.

답변

3

문제는 다른 질문으로 이어집니다 : 엔티티의 동시 수정을 처리하는 위치와 방법은 무엇입니까? 즉, 사용자 A와 사용자 B가 동일한 레코드를 편집하고 나중에 레코드를 저장하는 레코드 (사용자 B)는 편집 한 버전이 오래되어 StaleObjectStateException을 가져옵니다.

  1. 강제 "올바른"무차별 하나, 예컨대 유저 (B)의 버전을 확인 : 여기

    일부 아이디어이다 DB에서 레코드의 현재 버전을 검색하고 사용자 B 버전의 전체 상태를 적용합니다. 사용자 A가 변경되면 문제가됩니다. "전자 메일 주소"필드와 사용자 B가 "사용자 이름"필드를 변경했습니다. 이 접근 방식으로 사용자 A가 수행 한 모든 작업이 사라졌습니다. 이 접근법에서는 StaleObjectStateException을 잡아서 저장소 내부의 모든 것을 수정합니다.

  2. "스마트"접근 방식 : 접근 방식 1과 마찬가지로 모든 것이 저장소 내에 고정되어 있습니다 (예 : StaleObjectStateException을 완전히 포착하고 처리 함). 도메인 지식을 사용하여 사용자 B가 수행 한 일부 변경 만 선택적으로 적용합니다. 예 : 사용자 A가 전자 메일 주소를 변경하고 사용자 B가 사용자 이름을 변경 한 경우 해당 변경 사항은 서로 제외되지 않으므로 리포지토리는 전자 메일 주소 만 업데이트 할 수 있습니다. 이것은 레코드의 두 측면이 서로 직접적으로 의존하지 않고 동시에 변경된 경우에 효과적입니다. 이 솔루션을 구현하는 것은 "똑똑한"방법에 따라 다소 복잡 할 수 있습니다.

  3. 저장소 내에서 동시 변경을 거부합니다. 이 경우 StaleObjectStateException이 발생하면 저장소는 레코드를 저장할 수 없다는보고를해야합니다. 그것은 실제로 예외 거품을 내버려 둘 수 있습니다,하지만 당신은 NHibernate를 누출시키고 있습니다. 컨트롤러. 대신 도메인에 의미있는 유용한 세부 정보로 예외를 던질 수 있습니다. 이 상황에서 컨트롤러는 예외를 잡는 좋은 장소입니다. 그런 다음 예 : 무엇을 해야할지의 다른 옵션 :

    • 레코드가 다른 사용자에 의한 동시 변경으로 인해 저장할 수 없습니다 사용자를 알리고 처음부터 모든 일을 그에게 강요 멀리 모든 변경 사항을 던질 수 있습니다. 이것은 물론 사용자에게 고통스럽고 실제로는 거의 발생하지 않는 경우에만 수행해야합니다.
    • 사용자에게 문제를 알리고 사용자가 무엇을해야할지 결정하게합니다. 그의 변화를 강요하거나 다시 시작하십시오. 이 질문을 넘어 동안

,이 여전히 도움이되기를 바랍니다.

2

DI 컨트롤러에 이런 종류의 예외 관리를 사용하면 우려를 깨뜨릴 수 있습니다.

컨트롤러는 프리젠 테이션 레이어에 속하며 프리젠 테이션 레이어는 데이터 저장을 위해 무엇을 사용하고 있는지 알지 못하고 StaleObjectStateException은 NHibernate 항목입니다.

관련 문제