2010-05-12 5 views
1

.NET 3.5에서 사용자 지정 데이터 가져 오기 실행 파일을 가지고 있는데, SqlBulkCopy는 기본적으로 대량의 데이터를 빠르게 삽입합니다. 이 응용 프로그램은 기본적으로 입력 파일을 받아서 데이터를 마사지하고 SQL Server 2000으로 대량 업로드합니다. SQL 2008 데이터베이스 환경으로 구축 한 컨설턴트가 작성했습니다. 그 env 차이가 원인이 될까요? SQL 2000에는 BulkCopy의 기반이되는 bcp 유틸리티가 있습니다. 그래서 이것을 실행했을 때, 교착 상태 오류가 발생했습니다.SqlBulkCopy는 SQL Server 2000에서 교착 상태가 발생합니다.

오류 세부 정보 : 트랜잭션 (프로세스 ID 58)이 다른 프로세스에서 잠금 리소스에 교착 상태가 발생하여 교착 상태로 선택되었습니다. 트랜잭션을 재실행하십시오.

해결하기 위해 여러 가지 방법을 시도했습니다. 일시적으로 연결 문자열 변수 MultipleActiveResultSets = true를 설정하는 것이 이상적이지는 않지만 여전히 교착 상태 오류를 발생시킵니다. 또한 연결 시간 제한 문제가 아닌지 확인했습니다.

여기 기능이 있습니다. 어떤 충고?

/// <summary> 
    /// Bulks the insert. 
    /// </summary> 
    public void BulkInsert(string destinationTableName, DataTable dataTable) 
    { 
     SqlBulkCopy bulkCopy; 

     if (this.Transaction != null) 
     { 
      bulkCopy = new SqlBulkCopy 
       (
        this.Connection, 
        SqlBulkCopyOptions.TableLock, 
        this.Transaction 
       ); 
     } 
     else 
     { 
      bulkCopy = new SqlBulkCopy 
       (
        this.Connection.ConnectionString, 
        SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction 
       ); 
     } 

     bulkCopy.ColumnMappings.Add("FeeScheduleID", "FeeScheduleID"); 
     bulkCopy.ColumnMappings.Add("ProcedureID", "ProcedureID"); 
     bulkCopy.ColumnMappings.Add("AltCode", "AltCode"); 
     bulkCopy.ColumnMappings.Add("AltDescription", "AltDescription"); 
     bulkCopy.ColumnMappings.Add("Fee", "Fee"); 
     bulkCopy.ColumnMappings.Add("Discount", "Discount"); 
     bulkCopy.ColumnMappings.Add("Comment", "Comment"); 
     bulkCopy.ColumnMappings.Add("Description", "Description"); 


     bulkCopy.BatchSize = dataTable.Rows.Count; 
     bulkCopy.DestinationTableName = destinationTableName; 
     bulkCopy.WriteToServer(dataTable); 

     bulkCopy = null; 
    } 
+1

교착 상태 정보는 어떻습니까? 캡처 방법은 http://msdn.microsoft.com/en-us/library/ms190465.aspx를 참조하십시오. –

답변

0

꽤 정기적으로 BCP를 사용하고, 나는 이제까지 BatchSize에서이 전체를 대표하는 것은 아니다 1000

이 필드의 전형적인 값 이외로 설정 한 경우를 보지 못했다 행 수를 코드에 표시되어 있지만 복사 중에 서버에 전송할 관리 가능한 데이터 청크를 나타 내기 위해 IP 패킷 크기와 비슷합니다.

전체 테이블 대신이 값을 1000으로 변경해보십시오.

또한 SQL Enterprise Manager 또는 SQL Management Studio (클라이언트 도구 버전에 따라 다름)의 프로세스/잠금 관리자 창을보고 잠금과 관련하여 프로세스가 수행중인 작업을 확인할 수도 있습니다.

+0

BatchSize는 실제로 app.config의 매개 변수에 의해 설정됩니다. 각 rec마다 다른 테이블의 해당 값이 필요하기 때문에 플랫 파일 데이터를 임시 테이블로 정리합니다. 크기는 config의 var에 의해 결정됩니다.50 ~ 50000 정도의 다양한 크기로 배치 크기를 테스트했습니다. – stevenjmyu

+0

그러나 위의 코드 세그먼트는 코드에서 DataTable.Rows.Count 결과에 명시 적으로 설정되어 있음을 보여줍니다. 따라서이 구성 파일 값은 사용자 코드에 표시되지 않으므로 어디에서 작동하는지 알 수 있습니다. – Bill

0

이러한 삽입 작업은 동시에 수행됩니까? 클러스터 된 인덱스가있는 테이블에서 TABLOCK 힌트를 사용하여 동시 삽입을 수행 할 때 SqlBulkCopy와 관련된 알려진 문제점이 있습니다. 교착 상태가 발생합니다. 다음을 참조하십시오 :

http://msdn.microsoft.com/en-us/library/ms186341(SQL.90).aspx

+0

아니요, 병행 가져 오기를 수행하지 않습니다. 작성한 사람은 2008 년을 제외하고 많은 데이터베이스가없는 데이터베이스를 사용하여 로컬에서 실행할 수있었습니다. 대신 SqlBulkCopyOptions.Defaults를 설정하여 행 잠금을 설정했지만 교착 상태는 계속 보았습니다 . – stevenjmyu

0

다중 활성 결과 집합이 삽입에 대한 무관하다 - 나는 심지어 나중에 추가 된 이후 SQL 서버 2000을 지원하는 생각하지 않습니다.

SQL Server 2000에는 정교한 잠금 에스컬레이션이없는 최신 버전이 있습니다. 사용자가보고있는 것으로 예상됩니다. 나는 응용 프로그램이 일괄 삽입 이외의 대상 테이블에서 활동을하는 동안 컨설턴트가 대상 테이블에서 BCP 이외의 작업 부하를 가지고 있다고 가정합니다.

먼저 스테이징 테이블에 대량 삽입을 수행 한 다음 (교착 상태가 발생하지 않도록) 가능한 한 효율적으로 원시 SQL SP에 삽입/업데이트 쿼리 (많은 작은 배치 일 수도 있음)를 고려할 것입니다.

0

최종적으로 응용 프로그램 테스트를 위해 프로덕션 데이터베이스 (~ 50 기가)의 로컬 복사본을 얻을 수있었습니다. 탈착은 환경 문제였습니다. 고마워.

+0

축하합니다! 당신이 듣고 기뻐서 일하게 할 수있었습니다. – Garett

+1

그래서 환경 문제는 무엇입니까? 어떻게이 문제를 해결 했습니까? – skimania

+0

@stevenjmyu이 문제를 해결하기 위해 수행 한 단계를 나열 해주십시오. –

관련 문제