2016-08-24 8 views
2

SQLBulkCopy를 사용하여 실제로 대상에 데이터를 삽입하는 다음 코드가 있습니다. 이 코드는 교 x 상태로 인해 소스 SQL 서버에서 자주 실패합니다. 참고 복사되는 테이블을 사용할 수 있습니다 (일부 삽입/선택 실행중인 것) 대량 복사를 수행하는 동안 수 있습니다.SQLBulkCopy로 인해 교착 상태가 발생했습니다

"TABLOCK"힌트 또는 문제의 원인은 무엇입니까? 내 이해에 따라 TABLOCK은 공유 잠금만을 획득하므로 문제가되지 않습니다.

using (var reader = srcConnection.ExecuteReader($"select * from [{DatabaseName}].[{schemaName}].[{tableName}]")) 
{ 
    const SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers | 
               SqlBulkCopyOptions.KeepNulls | //Do not replace nulls with defaults in destination 
               SqlBulkCopyOptions.KeepIdentity; 
     //Use the identity values from source, do not generate identities in destination. 

    using (var bcp = new SqlBulkCopy(dstConnection.ConnectionString, bulkCopyOptions)) 
    { 
     const int threeMinutes = 60*3; 

     bcp.BulkCopyTimeout = threeMinutes; //Timeout is for a single batch 
     bcp.BatchSize = 5000; 
     bcp.DestinationTableName = $"[{DestinationDatabaseName}].[{schemaName}].[{tableName}]"; 
     bcp.EnableStreaming = true; 

     foreach (var col in table.Columns.Cast<Column>().Where(c => !c.Computed)) 
     { 
      bcp.ColumnMappings.Add(col.Name, col.Name); 
     } 

     bcp.WriteToServer(reader); 
    } 
} 
+0

을 실행하도록 설정합니다. 이 [link] (https://social.msdn.microsoft.com/Forums/sqlserver/en-US/932cd26c-53fc-49c0-b082-e7f5f05a9801/deadlock-when-using-sqlbulkcopy-to-concurrently-insert- single-non-empty-tables? forum = sqldatabaseengine) – Keppy

+0

대상을 동시에 채우지 않고 대상 테이블을 힙 (인덱스가 없음)으로 만듭니다. 교착 상태의 원인에 대한 자세한 것은 원본 테이블이지만 대상은 아닙니다. – SumanKumar

+0

TABLOCK에 대한 이해가 잘못되었다고 생각합니다. [MSDN의 문서] (https://msdn.microsoft.com/en-us/library/ms187373.aspx) "TABLOCK - 획득 한 잠금이 적용되도록 지정합니다. 테이블 레벨에서 ** 획득 된 잠금 유형은 ** ** * "(Emphases mine) 명령문에 따라 달라 지므로 TABLOCK을 사용한 선택은 공유 잠금 만 수행하지만 삽입 (예 :) 독점적 인 자물쇠를 취할 것입니다. –

답변

2

대량 삽입물은 테이블에 행을 삽입해야합니다. 행을 삽입하려면 배타적 잠금이 필요합니다. 획득 한 정확한 잠금은 동시성 모델에 따라 다릅니다.

TableLock 옵션을 지정하면 프로세스가 독점적 테이블 잠금을 획득하려고 시도합니다. 프로세스가 처음으로 공유 테이블 잠금을 획득하고 다른 프로세스가 행 잠금을 공유하며 두 프로세스 모두 잠금을 단독 잠금으로 업그레이드하려고하면 교착 상태가 발생할 수 있습니다.

가 여러 가지 방법이 교착 상태에 대한 자세한 정보를 얻을 수 있습니다 :

관련 문제