SqlBulkCopy : SqlBulkCopyOptions.UseInternalTransaction을 전달하고 전달하지 않는 것의 차이점은 무엇입니까?

.net sqlbulkcopy sql-server windows

문제

SqlBulkCopyOptions.UseInternalTransaction 복사 옵션을 사용하는 것과 사용하지 않는 차이점을 찾으려고 노력하고 있지만 내 테스트 응용 프로그램에서는 차이점을 발견하지 못합니다. 예를 들어 BatchSize 가 0이고 레코드 번호 50이 데이터베이스 테이블에 추가 할 때 오류를 발생시키는 100 개의 레코드 ( DataTable )를 추가하면 테이블에 0 레코드가 생깁니다. 예를 들어 BatchSize 를 10으로 설정하면 40 레코드 (10 레코드 중 4 배치, 5 레코드는 잘못된 레코드를 포함하므로 대량 복사가 중단됩니다.) S qlBulkCopyOptions.UseInternalTransaction 이 설정되었는지 여부는 중요하지 않습니다. 항상 동일한 결과를 얻습니다. 그것은 내부 트랜잭션에서 배치가 항상 복사되는 것 같습니다.

내 테스트 응용 프로그램에 관심이 있다면 여기에 있습니다 : SqlBulkCopy-Error-and-Transaction-Test.zip

내 질문은 다음과 같습니다.

  1. SqlBulkCopyOptions.UseInternalTransaction 때문에 쓸모 SqlBulkCopy 항상 내부 거래를 사용?
  2. 그렇지 않은 경우 :이 옵션의 실제 의미는 무엇입니까? 어느 경우에 차이가 있습니까?

누군가가 명확히 할 수 있기를 희망한다.

편집 : 답변과 의견에 따르면 내 문제는 충분히 명확하지 않다고 가정합니다. 나는 문서를 안다. "기본적으로 대량 복사 작업은 자체 트랜잭션입니다." UseInternalTransaction 전달할 때 각 일괄 처리는 자신의 트랜잭션을 사용합니다. 하지만 그것은 대량 복사 작업이 전체 대량 복사 (그리고 각 배치마다 하나씩)에 대해서만 하나의 트랜잭션을 사용한다는 것을 의미한다면 BatchSize를 특정 크기로 설정하면 데이터베이스에 레코드를 얻지 못하고 첫 번째 오류가 발생합니다. 하나의 트랜잭션 만 사용되는 경우 트랜잭션 로그에 추가 된 모든 레코드는 롤백됩니다. 그러나 결함 레코드가 포함 된 배치 앞에 놓여있는 배치 레코드를 얻습니다. 이것은 기본적으로 각 배치가 자체 트랜잭션으로 실행되는 것처럼 보입니다. 즉, UseInternalTransaction 전달했는지 여부는 아무런 차이가 없습니다. 내가 잘못된 길을 가고 있다면 누군가가 분명히 밝힐 수 있다면 정말 감사 할 것입니다.

한 가지 사실이 중요 할 수 있습니다. SQL Server 2012를 사용합니다. SQL Server 2008의 동작이 다를 수 있습니다. 나는 그것을 검사 할 것이다.

편집 : 덕분에 usr에서 답장 덕분에 나는 대답을 찾은 것 같아요 : 나는 조금 디버깅하고 프로파일 링 및 UseInternalTransaction 정의되지 않은 경우 개인 필드 _internalTransaction 실제로 설정되지 않은 것을 알게되었습니다. SqlBulkCopy는 자체 (내부) 트랜잭션을 사용하지 않습니다. 그러나 프로파일 링을 통해 SqlBulkCopy는 BatchSize와 관계없이 데이터 복사에 TDS (테이블 형식 데이터 스트림)를 사용함을 나타냅니다. 특히 SQL Server에 대한 TDS에 대한 많은 정보를 찾지 못했지만 SQL Server가 내부 트랜잭션에서 TDS 대량 복사 작업을 실행한다고 가정합니다. 따라서 UseInternalTransaction SQL 서버에 대한 일종의 중복 것,하지만 그것을 설정하는 것이 안전 측면에있을 것으로 보인다.

인기 답변

이 옵션을 설정하면 SQLBulkCopy 클래스는

_internalTransaction = _connection.BeginTransaction();

각 배치 주변.

그러나이 옵션은 기본적으로 트랜잭션이 자동 커밋 모드로 실행되므로 SQL Server와 실질적으로 차이가 없습니다.

유일하게 관찰 가능한 차이점은 외부 트랜잭션에서 전달하려고 시도하지 않은 유효성 검사를 수행한다는 것입니다.

다음은 모든 배치를 성공적으로 롤백합니다.

var transaction = sourceConnection.BeginTransaction();             
using (SqlBulkCopy bulkCopy =
    new SqlBulkCopy(sourceConnection, SqlBulkCopyOptions.Default, transaction))

{
    bulkCopy.BatchSize = 50;

    bulkCopy.DestinationTableName = "dbo.foobar";
        bulkCopy.WriteToServer(dt);
}

transaction.Rollback();

SqlBulkCopyOptions.UseInternalTransaction 전달하면 오류가 발생하면서 실패합니다.

동시에 SqlBulkCopyOption.UseInternalTransaction을 지정하고 외부 트랜잭션을 전달해야합니다.

SET IMPLICIT_TRANSACTIONS ON; 으로 SET IMPLICIT_TRANSACTIONS ON; 하면 차이가 있을지 궁금해했습니다 SET IMPLICIT_TRANSACTIONS ON; 이전에 자동 커밋 모드를 해제하기 위해 연결에서 실행되었지만 연결 개체를 사용하는 SqlBulkCopy 생성자의 오버로드가 "예기치 않은 기존 트랜잭션"을 반환합니다. 어쨌든 두 경우 모두 오류가 발생합니다. 연결 문자열을 사용하는 오버로드로 인해 새 연결이 만들어집니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.