추적 및 비추적 쿼리
EF core에서 쿼리를 실행할 때, EF core는 결과로 반환되는 엔티티에 대해서 내부적으로 추적(트래킹)을 할지 말지 결정할 수 있다. 이것은 쿼리의 성능 최적화 및 애플리케이션의 요구 사항에 따라 데이터를 관리하는 방법을 선택할 수 있게 해준다.
추적쿼리 Yes Tracking
추적쿼리는 ef core가 쿼리를 통해 반환된 에티티의 상태를 변경 감지를 위해 추적한다. 즉 EF CORE는 이 엔티티들에 대한 모든 변경 사항을 내부적으로 기록하고, SaveChanges() 를 호출할 때 이러한 변경 사항을 데이터베이스에 반영한다. 이 기능은 주로 데이터를 조회한 후 수정할 때 유용하고, 자동으로 변경 추적을 해주기 때문에 개발자가 별도로 상태를 관리할 필요가 없다.
using ( var context = new ApplicationContext() ){
var blog = context.Blogs.FirstOrDefault(b => b.blogId ==1 );
blog.Name = “Updated Blog Name”;
context.SaveChanges();
}
위 예시에서, FirstOrDefault 메서드를 통해서 조회된 blog 엔티티는 자동으로 EF core에 의해서 추적된다. 엔티티의 Name 속성을 변경한 후 SaveChanges()를 호출하면, EF core는 이 변경을 감지하고 데이터베이스에 업데이트 쿼리를 자동으로 실행한다.
비 추적 쿼리 No Tracking
비추적 쿼리는 EF core가 엔티티의 상태를 추적하지 않는다. 즉, 결과로 반환되는 엔티티에 대한 변경 사항을 EF core가 감지하거나 기록하지 않는다. 이 방식은 단순히 데이터를 읽기만 할 때에 유용하고, 성능 최적화에 도움이 된다. 왜냐하면, 내부적으로 변경 추적을 위한 추가적인 오버헤드가 발생하지 않기 때문이다.
*변경 추적은 오버헤드가 발생한다.
using ( var context = new ApplicationContext() ){
var blogs = context.Blogs
.AsNoTracking()
.Where( b=> b.Rating > 3)
.ToList();
}
AsNoTracking 메서드를 사용함으로써, 해당 쿼리로 조회되는 엔티티들은 EF core에 의해서 추적되지 않는다. 이는 주로 읽기 전용 데이터를 다룰 때 성능 이점을 제공한다.
사용 후 DbContext를 삭제하는 것은 중요하다. 이유는 다음과 같다.
1. 성능 최적화
DB Context는 내부적으로 여러가지 리소스를 관리한다. 데이터베이스 연결과 캐시된 데이터, 추적된 엔티티의 상태정보 등이 있다. DB Context 인스턴스가 지속적으로 증가하고 적절히 해제되지 않으면, 사용되지 않는 데이터베이스 연결이 열려있게 되거나, 필요이상의 메모리를 소비하게 되어 어플리케이션의 성능에 부정적인 영향을 줄 수 있다.
2. 메모리 누수 방지
DB Context 인스턴스가 적절히 해제되지 않는 경우에, 닷넷 가비지 컬렉터가 이를 회수할 수 없게 되어 메모리 누수가 발생할 수 있다. 장기 실행 어플리케이션에서는 이러한 메모리 누수가 점진적으로 메모리 사용량을 증가시키며, 결국 어플리케이션의 성능 저하나 시스템 자원의 고갈로 이어질 수 있다.
3. 데이터 무결성 유지
DB Context는 데이터 변경 사항의 추적 및 관리를 담당한다. 장시간 동안 DB Context 인스턴스를 사용하는 경우에, 변경 추적 정보가 계속 축적되어 오류의 가능성을 높이거나 예기치 않은 동작을 유발할 수 있다. 적절한 수명주기 관리를 통해서, 각 비즈니스 트랜잭션마다 새로운 DB Context 인스턴스를 사용함으로써 데이터의 일관성과 무결성을 보다 잘 보장할 수 있다.
4. 동시성 관리
DB Context는 동시성 관리에도 중요한 역할을 한다. 여러 사용자가 동시에 데이터를 변경하는 어플리케이션에서는 DB Context의 생명주기를 적절히 관리하여 동시성 충돌을 효과적으로 해결할 수 있다. 각 사용자 또는 요청마다 별도의 DB Context 인스턴스를 사용하면, 동시성 문제를 더욱 명확하게 식별하고 처리할 수 있다.
5. 정리
따라서 DbContext 인스턴스의 생성과 삭제를 적절히 관리하는 것은 어플리케이션의 성능 최적화, 메모리 관리, 데이터 무결성 유지, 그리고 동시성 문제 해결에 있어서 중요하다. .NET의 using 문을 활용하거나 종속성 주입패턴을 사용하여 DbContext의 수명주기를 효과적으로 관리하는 것이 좋다.