2011-02-28 2 views
8

데이터 업데이트/다시 시도를 위해 LINQ를 통해 액세스되는 MS SQL 2008 데이터베이스가 있습니다.Entity Framework == EntityException을 사용하여 데이터베이스에 동시 액세스

무거운 응용 프로그램에 대한 PerCall 인스턴스화 모드에서 WCF 서비스를 통해 내 linq에 액세스합니다. 이 응용 프로그램에는 서비스를 호출하는 스레드가 여러 개 있으며 여러 응용 프로그램이 sametime에서 실행 중입니다.

System.Data.EntityException이 잡힌 메시지는 공급자 연결에 대한 트랜잭션을 시작하는 동안 오류가 발생 =

나는 종종 일어나고 일부 EntityException을했습니다. 자세한 내용은 내부 예외를 참조하십시오. 자료 = System.Data.Entity 스택 트레이스 : System.Data.Objects.ObjectContext.SaveChanges에서 System.Data.EntityClient.EntityConnection.BeginTransaction()에서 System.Data.EntityClient.EntityConnection.BeginDbTransaction (IsolationLevel isolationLevel) 에서 (SaveOptions 옵션) D : \ Workspace \ XYZWASDF \ DataServer \ DataServer.cs의 Infoteam.GfK.TOMServer.DataServer.DataServer.SaveChanges()에서 : 줄 123 InnerException : System.Data.SqlClient.SqlException 메시지 = Une 누벨 트랜잭션은 세션을 자동으로 처리합니다. 출처 = 닷넷하는 SqlClient 데이터 공급자 있는 ErrorCode = -2146232060 클래스 = 16 LINENUMBER = 1 번호 = 3988 절차 = "" 서버 = IFT-srv114 주 = 1 스택 트레이스 : 의 System.Data.SQLClient에서 .SqlConnection.OnError (SqlException 예외, 부울 breakConnection) 에서 System.Data.SqlClient.SqlInternalConnection.OnError (SqlException 예외, 부울 breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 에서 System.Data.SqlClient. TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHand LER, TdsParserStateObject stateObj) System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest에서 (바이트 [] 버퍼 TransactionManagerRequestType 요청 문자열 transactionName, TransactionManagerIsolationLevel isoLevel, INT32 시간 초과 SqlInternalTransaction 트랜잭션, TdsParserStateObject stateObj 부울 isDelegateControlRequest)에서의 System.Data.SQLClient 시스템에서 System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction에서 .SqlInternalConnectionTds.ExecuteTransactionYukon (transactionRequest transactionRequest, 문자열 transactionName, IsolationLevel 이소, SqlInternalTransaction internalTransaction, 부울 isDelegateControlRequest) (transactionRequest transactionRequest, 문자열 이름, IsolationLevel 이소, SqlInternalTransaction internalTransaction, 부울 isDelegateControlRequest) .Data.SqlClient.SqlInternalConnection.BeginSqlTransac System.Data.Common.DbConnection.BeginTransaction에서 System.Data.SqlClient.SqlConnection.BeginDbTransaction (IsolationLevel isolationLevel) 에서 System.Data.SqlClient.SqlInternalConnection.BeginTransaction (IsolationLevel의 ISO) 에서 기 (IsolationLevel의 ISO, 문자열 transactionName) (System.Data.EntityClient.EntityConnection.BeginDbTransaction에서 isolationLevel isolationLevel) (isolationLevel isolationLevel) 의 InnerException :

(죄송합니다 아주 읽을 수 없습니다입니다). (내부 예외 메시지는 "세션에서 실행중인 다른 스레드가 있기 때문에 새로운 트랜잭션이 허용되지 않습니다."

는 나는이 예외을 할 때 그것은 순전히 무작위, 난 루프에서 아니에요 확인했습니다, 나는이 문제를 방지하는 방법에 대한 아무 생각도 없어 어떤 도움이 정말 이해할 수있을 것이다

을. :)

감사합니다

편집을! 저는 여기에 코드를 보지 않고 가끔

//My DataServer method, which is a singleton 

    [MethodImpl(MethodImplOptions.Synchronized)] 
      public void SaveChanges() 
      { 
       lock (_lockObject) 
       { 
        try 
        { 
         _context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); 
         _changeListener.ManageIDAfterInsert();      
        } 
        catch (Exception ex) 
        { 
         Logger.Instance.Error("[DataServer:SaveChanges] Got an error when trying to save an object", ex); 
         //HERE I've this error 
        } 
       } 
      } 

//One example where I can have exception sometimes, this is called through a WCF service, so I have a method which attach the object and then save it 
private OrderStatus AddOrderStatus(OrderStatus orderStatus) 
     { 
      DataServer.DataServer.Instance.InsertOrUpdateDetachedObject(orderStatus); 

      return orderStatus; 
     } 
+1

이 오류의 원인이되는 코드를 표시 할 수 있습니까? –

답변

7

이 예외를 어디서 얻었의 예입니다, 짧은 대답이다 EntityFram ework은 스레드로부터 안전하지 않습니다. ObjectContext에 액세스하려고 시도 할 때 두 개의 + 스레드가 겹쳐지면이 오류가 겉으로는 임의의 패턴으로 나타납니다. 나는 문맥을 static 변수에 채웠다 고 가정합니다. 컨텍스트를 로컬 변수로 만들거나 ObjectContext에 액세스 할 수 있도록 잠금을 작성하십시오.

코드를 게시하면보다 구체적인 답변을 얻을 수 있습니다.

편집

귀하의 문제는 두 스레드가 동시에 문맥을 사용하려고, 또는 1 개 스레드를 연 다음 트랜잭션을 떠나와 두 번째 스레드가 단일 컨텍스트를 사용하려고 시도를 통해 오는 것입니다. 코드 조각은 이전보다 더 많은 질문을 제기합니다.

  • 코드 예제에서 _ lockObject은 정적 변수입니까?
  • 왜 잠금을 SaveChanges에 표시하지만 오류가 던져지고 있다고 설명합니까 InsertOrUpdateDetachedObject에서? InsertOrUpdateDetachedObject 코드를 볼 수 있습니까?
  • SaveChanges는 컨텍스트에 직접 액세스하는 다른 모든 메서드와 동일한 _lockObject을 사용합니까?
  • _context.SaveChanges으로 전화하시는 것이 DB에 저장하는 유일한 방법입니까, 아니면 다른 곳에서 트랜잭션 컨텍스트를 여는 방법이 있습니까?
  • 싱글 톤을 사용하므로 여러 통화에서 컨텍스트가 공유됩니다. 모든 WFC 호출마다 새로운 새 컨텍스트를 인스턴스화하는 것이 좋습니다.
+0

가끔 충돌이 발생하는 예를 추가했습니다. dataserver를 만드는 My DataServer는 싱글 톤이지만 differentCall이 동일한 컨텍스트를 가지고 있지 않은 PerCall 인스턴스화를 가지고 있기 때문에 그럴 것이라고 생각합니다. – J4N

+0

안녕하세요. 위의 답을 얻지 못했습니다. 나 한테 그걸 정리 해줄 수있어? – JGC