2015-01-26 1 views
0

우리는 Azure에서 호스팅되는 작업자 역할이 있으며 해당 데이터베이스에 SQL Azure를 사용합니다. 이 오류는 다음과 같은 오류와 함께 실패합니다 연결/트랜잭션을 만들기 위해, 다음의 모든 시도가 발생하면 System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)SQL 열기 실패로 인해 응용 프로그램 풀이 재활용 될 때까지 시간 초과로 인해 체계적인 TransactionAbortedException이 발생합니다.

: System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.TimeoutException: Transaction Timeout은 본질적으로 우리의 모든 서비스 이후 사용할 수없는 우리의 전체 서비스를 (렌더링 때때로는 SQL 연결 오류가있을 것입니다 데이터베이스 액세스 필요).

우리가 발견 한 유일한 해결책은 수동으로 응용 프로그램 풀을 재활용하는 것입니다. 분명히 이것은 문제가 발생할 때마다 누군가가 수동으로 응용 프로그램 풀을 재활용 할 때까지 인스턴스가 서비스 요청을 처리 할 수 ​​없기 때문에 문제가됩니다.

분명히 우리는 문제 해결을위한 해결책이나 응용 프로그램 풀 재활용 (또는 비슷한 결과를 얻을 수있는) 자동화를위한 대안을 찾고 있습니다.

우리는 Entity Framework 4 (기존 프로젝트, 그대로 작동하며 아직 업그레이드 할 이유가 없음)를 사용 중입니다. 따라서 EF4는 각 쿼리 또는 SaveChanges 호출에 대해 데이터베이스 연결을 열거 나 닫을 것이므로 코드에서 ObjectContext.Connection.Open()을 사용하여 트랜잭션을 만들 때 연결을 강제로 열어 여러 개의 쿼리 또는 업데이트가있는 경우 트랜잭션을 MSDTC로 보내지 않도록합니다 동일한 거래. 이 초기 열기 중에 예외가 발생합니다.

TransactionScope의 경우 TransactionScopeOption.RequiredIsolationLevel.ReadCommitted을 사용하고 있습니다.

답변

0

해결책이 발견되었습니다!

EFTransactionTransactionScopeObjectContext을 둘 다 감싸서 범위 및 연결 열기를 자동화합니다. 이 코드는이 형태의 생성자에서 발견되었다 : 클래스 자체가 IDisposable입니다

this._transactionScope = new TransactionScope(transactionScopeOption, transactionOptions); 
this.OpenConnection(); 

하는 동안 예외가 생성자 내에서 일어나고있다. 따라서 객체에 대한 참조가 할당되지 않고 Dispose()이 호출되지 않습니다. 따라서 _transactionScope 필드가 절대로 처리되지 않고 트랜잭션이 limbo에 걸려 다음 트랜잭션 요청이 시간 초과됩니다.

해결책은 두 가지입니다. 첫째, 클래스에 finalizer를 구현하십시오. 파이널 라이즈 실행 시간은 정의되어 있지 않지만 보류중인 트랜잭션을 림보 (limbo)에 남겨 두는 것이 좋습니다. 적어도 어느 시점에서는 객체가 GC로 처리되고 트랜잭션이 처리되고 다른 트랜잭션이 다시 시작됩니다.

둘째, 개방이 실패 할 경우 시도/캐치에 this.OpenConnection()Dispose() 트랜잭션을 포장 :

this._transactionScope = new TransactionScope(transactionScopeOption, transactionOptions); 
try 
{ 
    this.OpenConnection(); 
} 
catch 
{ 
    this._transactionScope.Dispose(); 
    throw; 
} 

이 예외 케이스를 처리하고 보류중인 "좀비"거래를 남기지 않습니다.

관련 문제