트랜잭션 커밋 오류 처리
참고 항목
EF6.1 이상만 - 이 페이지에서 다루는 기능, API 등은 Entity Framework 6.1에 도입되었습니다. 이전 버전을 사용하는 경우 이 정보의 일부 또는 전체가 적용되지 않습니다.
6.1의 일부로 EF에 대한 새로운 연결 복원력 기능인 일시적인 연결 실패가 트랜잭션 커밋 승인에 영향을 줄 때 자동으로 검색하고 복구하는 기능이 도입되었습니다. 시나리오의 전체 세부 정보는 SQL Database 연결 및 멱등 문제 블로그 게시물에 가장 잘 설명되어 있습니다. 요약하자면, 이 시나리오는 트랜잭션 커밋 중에 예외가 발생할 때 두 가지 가능한 원인이 있다는 것입니다.
- 서버에서 트랜잭션 커밋이 실패했습니다.
- 서버에서 트랜잭션 커밋이 성공했지만 연결 문제로 인해 성공 알림이 클라이언트에 도달하지 못했습니다.
첫 번째 상황이 발생하면 애플리케이션 또는 사용자가 작업을 다시 시도할 수 있지만 두 번째 상황이 발생하면 재시도를 피해야 하며 애플리케이션이 자동으로 복구될 수 있습니다. 문제는 커밋 중에 예외가 보고된 실제 이유를 검색할 수 없는 경우 애플리케이션이 올바른 작업 과정을 선택할 수 없다는 것입니다. EF 6.1의 새로운 기능을 사용하면 트랜잭션이 성공한 경우 EF에서 데이터베이스를 다시 확인하고 올바른 작업 과정을 투명하게 수행할 수 있습니다.
기능 디자이너 사용
기능을 사용하도록 설정하려면 DbConfiguration의 생성자에 SetTransactionHandler에 대한 호출을 포함해야 합니다. DbConfiguration에 익숙하지 않은 경우 코드 기반 구성을 참조하세요. 이 기능은 EF6에서 도입한 자동 재시도와 함께 사용할 수 있습니다. 이는 일시적인 오류로 인해 트랜잭션이 실제로 서버에서 커밋되지 않은 경우에 도움이 됩니다.
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetTransactionHandler(SqlProviderServices.ProviderInvariantName, () => new CommitFailureHandler());
SetExecutionStrategy(SqlProviderServices.ProviderInvariantName, () => new SqlAzureExecutionStrategy());
}
}
트랜잭션 추적 방법
기능을 사용하도록 설정하면 EF는 __Transactions라는 데이터베이스에 새 테이블을 자동으로 추가합니다. EF에서 트랜잭션을 만들고 커밋 중에 트랜잭션 오류가 발생하는 경우 해당 행이 있는지 확인할 때마다 이 테이블에 새 행이 삽입됩니다.
EF는 더 이상 필요하지 않은 경우 테이블에서 행을 정리하기 위해 최선을 다하지만, 애플리케이션이 조기에 종료되면 테이블이 증가할 수 있으며, 이러한 이유로 경우에 따라 테이블을 수동으로 제거해야 할 수 있습니다.
이전 버전에서 커밋 실패를 처리하는 방법
EF 6.1 이전에는 EF 제품의 커밋 실패를 처리하는 메커니즘이 없었습니다. 이전 버전의 EF6에 적용할 수 있는 이 상황을 처리하는 방법에는 여러 가지가 있습니다.
옵션 1 - 아무 것도 수행하지 않음
트랜잭션 커밋 중 연결 실패 가능성이 낮으므로 이 조건이 실제로 발생하는 경우 애플리케이션이 실패하는 것이 허용될 수 있습니다.
옵션 2 - 데이터베이스를 사용하여 상태 다시 설정
- 현재 DbContext 삭제
- 새 DbContext를 만들고 데이터베이스에서 애플리케이션의 상태를 복원합니다.
- 마지막 작업이 성공적으로 완료되지 않았을 수 있음을 사용자에게 알릴 수 있습니다.
옵션 3 - 수동으로 트랜잭션 추적
- 트랜잭션 상태를 추적하는 데 사용되는 데이터베이스에 추적되지 않는 테이블을 추가합니다.
- 각 트랜잭션의 시작 부분에 있는 테이블에 행을 삽입합니다.
- 커밋 중에 연결이 실패하면 데이터베이스에 해당 행이 있는지 확인합니다.
- 행이 있는 경우 트랜잭션이 성공적으로 커밋되었으므로 정상적으로 계속합니다.
- 행이 없는 경우 실행 전략을 사용하여 현재 작업을 다시 시도합니다.
- 커밋에 성공하면 테이블이 증가하지 않도록 해당 행을 삭제합니다.
이 블로그 게시물에는 SQL Azure에서 이 작업을 수행하기 위한 샘플 코드가 포함되어 있습니다.
.NET