개요
이 가이드 에서는 EF Core Provider 애플리케이션에서 트랜잭션을 사용하는 방법을 학습 수 있습니다. 트랜잭션 은 일련의 쓰기 (write) 작업을 래핑합니다. 트랜잭션 의 작업이 실패하면 제공자 트랜잭션 의 모든 변경 사항을 롤백합니다. 이 동작은 데이터 일관성 보장하는 데 도움이 됩니다.
EF Core Provider는 다음 트랜잭션 모드를 지원합니다.
암시적 트랜잭션: 제공자 트랜잭션 에서
SaveChanges()및SaveChangesAsync()메서드에 대한 호출을 자동으로 래핑합니다. 이 동작을 구성하거나 비활성화하는 방법을 학습 암시적 트랜잭션 구성을 참조하세요.명시적 트랜잭션:
Database.BeginTransaction()메서드를 호출하여 트랜잭션 수동으로 시작한 다음 또는 를 호출하여 트랜잭션 커밋Commit()하거나Rollback()롤백합니다.
샘플 데이터
이 가이드 의 예제에서는 sample_guides 데이터베이스 의 planets 컬렉션 사용합니다. 이 컬렉션 의 문서는 다음 Planet 클래스를 모델로 사용합니다.
public class Planet { public ObjectId _id { get; set; } public string name { get; set; } = null!; public int orderFromSun { get; set; } public bool hasRings { get; set; } }
이 컬렉션 Atlas 에서 제공하는 샘플 데이터 세트에서 가져온 것입니다. 퀵 스타트 가이드 참조하여 무료 MongoDB cluster 생성하고 이 샘플 데이터를 로드하는 방법을 학습 .
요구 사항 및 제한 사항
트랜잭션을 사용하기 전에 다음 요구 사항 및 제한 사항에 유의하세요.
트랜잭션에는 복제본 세트 또는 샤딩된 클러스터 와 같은 다중 문서 트랜잭션을 지원하는 MongoDB Server 배포서버 필요합니다. 애플리케이션 독립형 배포서버 에서 트랜잭션 시작하려고 하면 제공자 가 을
NotSupportedException발생시킵니다. 이를 방지하려면 암시적 트랜잭션 구성에 설명된 대로AutoTransactionBehavior.Never를 설정하다 .EF Core 제공자는
System.Transactions.TransactionScope에서 만든 트랜잭션과 같은 .NET 앰비언트 트랜잭션을 지원 하지 않습니다. 앰비언트 트랜잭션(ambient transaction)을 사용하려고 하면 제공자 예외를 발생시킵니다. 대신 암시적 또는 명시적 트랜잭션을 사용합니다.
암시적 트랜잭션
기본값 으로 여러 루트 엔터티가 영향을 받는 경우 EF Core Provider는 트랜잭션 SaveChanges() SaveChangesAsync() 에서 및 호출을 자동으로 래핑합니다. 루트 엔터티는 다른 문서 내에 저장되는 소유 유형 또는 내장된 유형과 달리 컬렉션 의 최상위 문서 입니다.
다음 예시 에서는 단일 SaveChanges() 호출에 두 개의 행성을 삽입합니다. 이 작업은 둘 이상의 루트 엔터티에 영향을 미치므로 제공자 자동으로 이를 트랜잭션 으로 래핑합니다. 둘 중 하나의 삽입이 실패하면 제공자 두 변경 사항을 모두 롤백합니다.
Synchronous 또는 Asynchronous 탭을 선택하여 해당 코드를 확인합니다.
dbContext.Planets.AddRange( new Planet { Name = "Mercury" }, new Planet { Name = "Venus" } ); // Both inserts succeed or both are rolled back dbContext.SaveChanges();
dbContext.Planets.AddRange( new Planet { Name = "Mercury" }, new Planet { Name = "Venus" } ); // Both inserts succeed or both are rolled back await dbContext.SaveChangesAsync();
암시적 트랜잭션 구성
DbContext 객체 의 Database.AutoTransactionBehavior 속성 은 제공자 암시적 트랜잭션을 사용하는 시기를 제어합니다. 이 속성 다음 값을 포함하는 AutoTransactionBehavior 열거형 의 값을 허용합니다.
값 | 설명 |
|---|---|
| 제공자 |
| 제공자 단일 엔터티 작업의 경우에도 항상 트랜잭션 사용합니다. |
| 제공자 트랜잭션 사용하지 않습니다. |
다음 예시 와 같이 SaveChanges() 또는 SaveChangesAsync() 메서드를 호출하기 전에 점 이 속성 설정하다 수 있습니다. Synchronous 또는 Asynchronous 탭 선택하여 해당 코드를 확인합니다.
dbContext.Database.AutoTransactionBehavior = AutoTransactionBehavior.Never; // This SaveChanges() call will not use a transaction dbContext.Planets.Add(new Planet { Name = "Mars" }); dbContext.SaveChanges();
dbContext.Database.AutoTransactionBehavior = AutoTransactionBehavior.Never; // This SaveChangesAsync() call will not use a transaction dbContext.Planets.Add(new Planet { Name = "Mars" }); await dbContext.SaveChangesAsync();
명시적 트랜잭션
명시적 트랜잭션을 사용하여 여러 SaveChanges() 호출 및 기타 작업을 단일 원자 작업 단위로 그룹 할 수 있습니다. 명시적 트랜잭션 시작하려면 Database.BeginTransaction() 또는 Database.BeginTransactionAsync() 메서드를 호출합니다. 작업을 수행한 후 Commit() 또는 CommitAsync() 를 호출하여 트랜잭션 완료합니다.
다음 예시 여러 작업을 단일 트랜잭션 으로 래핑하여 이 패턴 보여 줍니다. 작업에서 예외가 발생하면 제공자 트랜잭션 의 모든 변경 사항을 자동으로 롤백합니다. Synchronous 또는 Asynchronous 탭 선택하여 해당 코드를 확인합니다.
using var transaction = dbContext.Database.BeginTransaction(); var planet = dbContext.Planets.First(p => p.Name == "Mercury"); planet.Name = "Mercury (Updated)"; dbContext.SaveChanges(); dbContext.Planets.Add(new Planet { Name = "Venus" }); dbContext.SaveChanges(); transaction.Commit();
await using var transaction = await dbContext.Database.BeginTransactionAsync(); var planet = await dbContext.Planets.FirstAsync(p => p.Name == "Mercury"); planet.Name = "Mercury (Updated)"; await dbContext.SaveChangesAsync(); dbContext.Planets.Add(new Planet { Name = "Venus" }); await dbContext.SaveChangesAsync(); await transaction.CommitAsync();
팁
수동 롤백
이 페이지의 예제에서는 using 선언을 사용하여 트랜잭션을 자동으로 롤백하고 트랜잭션 객체를 삭제합니다. 트랜잭션 을 수동으로 롤백하려면 catch 차단 에서 Rollback() 또는 RollbackAsync() 메서드를 호출합니다.
명시적 트랜잭션 구성
TransactionOptions 객체 BeginTransaction() 또는 BeginTransactionAsync() 메서드에 전달하여 트랜잭션 에 대한 읽기 고려 (read concern), 쓰기 고려 (write concern), 읽기 설정 (read preference) 및 최대 커밋 시간을 구성할 수 있습니다.
TransactionOptions 클래스에는 다음과 같은 속성이 있습니다.
속성 | 유형 | 설명 |
|---|---|---|
|
| 트랜잭션 의 첫 번째 명령에 대한 읽기 고려입니다. 기본값 은 |
|
| 트랜잭션 내 읽기 작업에 대한 읽기 기본 설정입니다. 트랜잭션은 프라이머리 에서 읽어야 합니다. 기본값 은 |
|
|
|
|
| 단일 |
다음 예시 Majority의 ReadConcern 을(를) 사용하여 트랜잭션 시작합니다. Synchronous 또는 Asynchronous 탭 선택하여 해당 코드를 확인합니다.
var options = new TransactionOptions( readConcern: new Optional<ReadConcern>(ReadConcern.Majority) ); using var transaction = dbContext.Database.BeginTransaction(options); var planet = dbContext.Planets.First(p => p.Name == "Mercury"); planet.Name = "Mercury (Updated)"; dbContext.SaveChanges(); transaction.Commit();
var options = new TransactionOptions( readConcern: new Optional<ReadConcern>(ReadConcern.Majority) ); await using var transaction = await dbContext.Database.BeginTransactionAsync(options); var planet = await dbContext.Planets.FirstAsync(p => p.Name == "Mercury"); planet.Name = "Mercury (Updated)"; await dbContext.SaveChangesAsync(); await transaction.CommitAsync();
읽기 고려 (read concern), 쓰기 고려 (write concern) 및 읽기 설정 (read preference) 에 대해 자세히 학습 읽기 고려, 쓰기 고려 및읽기 설정을 참조하세요.
트랜잭션 제한
트랜잭션을 사용할 때는 다음과 같은 제한 사항 및 주의 사항이 적용 .
배포서버 에서자동 트랜잭션을 지원 하지 않는 경우에만 자동 트랜잭션을 비활성화합니다. 자동 트랜잭션을 비활성화하면 데이터 불일치가 발생할 수 있으며 낙관적 동시성을 사용할 수 없습니다.
MongoDB Server 중첩 트랜잭션을 지원 하지 않습니다. 트랜잭션 이미 활성화된 상태에서
BeginTransaction()또는BeginTransactionAsync()를 호출하면 제공자InvalidOperationException를 발생시킵니다.MongoDB Server 트랜잭션 세이브포인트를 지원 하지 않습니다. 전체 트랜잭션 커밋 하거나 롤백해야 합니다.
기본값 으로 MongoDB Server
transactionLifetimeLimitSeconds서버 매개변수에 의해 제어되는 60 초 이상 실행되는 모든 트랜잭션 중단합니다. 이 제한은 암시적 트랜잭션과 명시적 트랜잭션 모두에 적용됩니다. 트랜잭션 이 시간 제한을 초과하면 MongoDB Server 트랜잭션을 중단하고 제공자 오류를 발생시킵니다. 트랜잭션 내에서 외부 API 호출과 같은 장기 실행 작업을 수행하지 않도록 합니다.MongoDB Server 네트워크 중단이 발생하거나 복제본 세트 투표 수행해야 하는
TransientTransactionError경우 오류를 반환할 수 있습니다. 이러한 경우 EF 핵심 제공자는 트랜잭션 자동으로 재시도하지 않습니다. 일시적인 트랜잭션 오류 및 재시도 전략에 대해 자세히 학습 보려면 트랜잭션 오류 처리를 참조하세요.
추가 정보
이 가이드 의 개념에 대해 자세히 학습 다음 리소스를 참조하세요.
이 가이드 에 사용된 메서드에 대해 자세히 학습 다음 .NET API 문서를 참조하세요.