3월, 2020의 게시물 표시

[C#/EF6] 서로 다른 컨텍스트가 업데이트된 레코드를 읽어야 할 때

여러개의 컨텍스트 사용 필연 우선 이 글은 커넥션 풀링과는 아주 관계가 없진 않으나, 관계가 없다고 생각한 채 읽으셔도 됨을 알려드립니다. 엔티티 프레임워크를 사용해 개발하다 보면 어쩔 수 없이 동일한 컨텍스트 클래스의 인스턴스를 여러 곳에서 생성해 사용하게 됩니다. 처음에 저는 단순한 프로젝트이니 그냥 컨텍스트 클래스를 싱글톤 패턴으로 만들어, 여러 사용처에서 호출해 사용하면 되지 않을까? 라는 어리석은 생각을 했으나, 아무리 단순한 프로젝트라도 그곳에 이벤트가 있고, 병렬 처리가 있다면, 그리고 그 곳에서 DB에 접근해야 한다면(즉, 컨텍스트 인스턴스 호출을 해야 한다면), 어쩔 수 없습니다. 싱글톤은 답이 아닙니다. 문제는 이렇게 할 경우에 여러 동일한 컨텍스트 클래스의 인스턴스에서 동일한 Entity의 정보를 읽고 쓸 수 있다는 것입니다. 예를 들어 동일한 컨텍스트 클래스의 서로 다른 인스턴스를 호출해 사용하는 A, B 클래스가 있다고 가정해봅시다. 아래 가정은 시간 순서로 쓰여졌습니다. B 인스턴스에서 Road 엔티티를 DB에서 컨텍스트로 읽어드렸습니다. (DB => In memory, FindAsync 사용) B 인스턴스에서 Road 엔티티의 (ICollection )Cars.Count 프로퍼티를 읽어 변수 prevCarCount 에 저장했습니다. B 인스턴스에서 유틸리티 클래스인 A 인스턴스의 AddCarOnRoad 를 호출했습니다. A 인스턴스에서 Road 엔티티의 (ICollection )Cars 프로퍼티를 수정했습니다. (새 컨텍스트 인스턴스에서 작업) B 인스턴스에서 Road 엔티티의 (ICollection )Cars.Count 프로퍼티를 읽어 변수 curCarCount 에 저장했습니다. B 인스턴스에서 prevCarCount와 curCarCount가 같으면 throw, 아니면 반환합니다. 위와 같은 상황에서, 어떤 한 로직을 빠뜨리면 3. 에서 Car 를 Road