DbContext 스레드는 안전합니까?
DbContext
클래스가 스레드로부터 안전한지 궁금합니다. 현재 DbContext
내 응용 프로그램에서에 액세스하는 병렬 스레드를 실행 하고 있으며 스레드와 관련된 것처럼 보이는 잠금 예외 및 기타 항목이 호스트되고 있기 때문에 그렇지 않다고 가정합니다 .
최근까지는 오류가 발생하지 않았지만 최근까지 DbContext
스레드에서 액세스하지 못했습니다 .
내가 옳다면 사람들은 해결책으로 무엇을 제안할까요?
스레드로부터 안전하지 않습니다. DbContext
스레드에서 의 새 인스턴스를 만들기 만하면 됩니다.
아니요 스레드로부터 안전하지 않습니다. EF 컨텍스트를 공유해서는 안되므로 전체 EF는 스레드로부터 안전하지 않습니다.
수정 됨-아래의 이전 답변.
이제는 항상 DbContext와 함께이 패턴을 사용합니다.
using(var db = new LogDbContext())
{
// Perform work then get rid of the thing
}
요청 스레드 당 하나의 접근 방식은 다른 DbContext 인스턴스가 그 뒤에있는 실제 데이터베이스에 새 값을 쓰는 동안에도 DbContext의 캐시 된 개체가 계속 유지되고 부실해 짐을 의미했습니다. 이것은 예를 들어 삽입을 수행하는 하나의 요청과 해당 쿼리에 대한 캐시 된 오래된 데이터 목록이있는 다른 스레드에서 들어오는 목록에 대한 다음 요청과 같은 이상한 문제를 만듭니다.
아래 작업을 수행하고 많은 읽기 / 작은 쓰기 스타일 앱의 성능을 향상시키는 접근 방식이 있지만 위의 훨씬 단순한 패턴보다 더 많은 디자인과 전략이 필요합니다.
최신 정보
또한 호출 로깅과 같은 라이브러리 메서드에 유용한 도우미 메서드를 사용합니다. 도우미 메서드는 다음과 같습니다.
public static async Task Using(Db db, Func<Db, Task> action)
{
if (db == null)
{
using (db = new Db())
{
await action(db);
}
}
else
{
await action(db);
}
}
이를 통해 호출되는 방식에 따라 기존 DbContext (선택 사항)를 사용하거나 사용 컨텍스트 내에서 인스턴스화하는 코드를 쉽게 작성할 수 있습니다.
예를 들어 DbContext로 작업하는 동안 일부 데이터를로드하고 일부 정보를 기록한 다음 해당 데이터를 저장할 수 있습니다. 성능 측면에서 동일한 DbContext로이 모든 작업을 수행하는 것이 가장 좋습니다. 반면에 간단한 작업에 대한 응답으로 무언가를 기록하고 다른 데이터를로드하거나 쓰지 않을 수도 있습니다. 위의 방법을 활용하면 기존 DbContext 내에서 작업하든 원하지 않든 상관없이 작동하는 하나의 로깅 방법 만 가질 수 있습니다.
public async Task WriteLine(string line, Db _db = null)
{
await Db.Using(_db, db => {
db.LogLines.Add(new LogLine(line));
await db.SaveChangesAsync();
});
}
이제이 메서드 호출은 기존 DbContext 내부 또는 외부에서 호출 할 수 있으며이 버전과 다른 모든 편리한 로깅 메서드 또는 내가 가지고있는 다른 유틸리티 메서드를 알고 있어야하는 대신 올바른 방식으로 작동합니다. 그들 또는 그들의 전화를 건 모든 전화의 맥락을 계획하십시오. 이것은 기본적으로 아래의 threadstatic 전략의 이점 중 하나를 반환합니다. 여기서 db가 유틸리티 호출에서 정확히 언제 열렸는지 걱정할 필요가 없습니다.
이전 답변
나는 일반적으로 EF DbContext로 스레드 안전성을 다음과 같이 처리합니다.
public class LogDbContext : DbContext
{
. . .
[ThreadStatic]
protected static LogDbContext current;
public static LogDbContext Current()
{
if (current == null)
current = new LogDbContext();
return current;
}
. . .
}
이를 통해 다음과 같이이 스레드에 대한 DbContext를 얻을 수 있습니다.
var db = LogDbContext.Current();
It's important to notice that since each DbContext keeps its own local cache, each thread will now have its own separate cache of entity objects, which can introduce some crazy behavior if you're not prepared for it. However, creating new DbContext objects can be expensive, and this approach minimizes that cost.
ReferenceURL : https://stackoverflow.com/questions/6126616/is-dbcontext-thread-safe
'IT이야기' 카테고리의 다른 글
SQL IN 연산자에 해당하는 linq는~? (0) | 2021.04.08 |
---|---|
ASP.NET MVC3의 부분보기에서 ViewBag에 액세스 할 수 없습니다. (0) | 2021.04.08 |
URL을 일반 Windows 파일 이름 Java로 변환 (0) | 2021.04.08 |
bash 함수 반환 값을 테스트하는 적절한 방법 (0) | 2021.04.08 |
플래시를 사용하지 않고 선택한 텍스트를 클립 보드에 복사 (0) | 2021.04.06 |