2014-10-27 13 views
12

Tôi chèn dữ liệu thông qua SqlBulkCopy như vậy:SqlBulkCopy có tự động bắt đầu một giao dịch không?

public void testBulkInsert(string connection, string table, DataTable dt) 
{ 
    using (SqlConnection con = new SqlConnection(connection)) 
    { 
     con.Open(); 

     using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con)) 
     { 
      bulkCopy.DestinationTableName = table; 
      bulkCopy.WriteToServer(dt); 
     } 
    } 
} 

Liệu điều này tự động được bao bọc trong một giao dịch SQL để nếu một cái gì đó đi cách nửa sai qua DB sẽ bị bỏ lại trong tình trạng tương tự như nó đã được trước chèn số lượng lớn đã bắt đầu? Hay một nửa dữ liệu sẽ được chèn vào?

nghĩa là nó cần thiết cho tôi để gọi một cách rõ ràng con.BeginTransaction

Hoặc nếu tôi gọi constructor SqlBulkCopy 's mà phải mất một chuỗi, đó là một cách tốt hơn để nhận nó xảy ra trong một giao dịch?

public void testBulkInsert(string connection, string table, DataTable dt) 
{ 
    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection)) 
    { 
     bulkCopy.DestinationTableName = table; 
     bulkCopy.WriteToServer(dt); 
    } 
} 

tôi tìm ra docs một chút không rõ ràng về vấn đề này khi họ bước đầu nêu rằng

Theo mặc định, một hoạt động sao chép số lượng lớn được thực hiện như một hoạt động cô lập. Các hoạt động sao chép số lượng lớn xảy ra trong một cách không giao dịch, không có cơ hội cho cán nó trở lại

nhưng sau đó nhà nước sau

Theo mặc định, một hoạt động sao chép số lượng lớn là giao dịch riêng của mình. Khi bạn muốn thực hiện thao tác sao chép hàng loạt chuyên dụng, hãy tạo một phiên bản mới của SqlBulkCopy bằng chuỗi kết nối hoặc sử dụng đối tượng SqlConnection hiện có mà không có giao dịch đang hoạt động. Trong mỗi trường hợp, thao tác sao chép hàng loạt sẽ tạo và sau đó cam kết hoặc cuộn lại giao dịch .

Vậy là nó cần thiết để làm:

public void testBulkInsert(string connection, string table, DataTable dt) 
{ 
    using (SqlConnection con = new SqlConnection(connection)) 
    { 
     con.Open(); 
     using (SqlTransaction tr = con.BeginTransaction(IsolationLevel.Serializable)) 
     { 
      using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, tr)) 
      { 
       bulkCopy.DestinationTableName = table; 
       bulkCopy.WriteToServer(dt); 
      } 
      tr.Commit(); 
     } 
    } 
} 
+0

Tại sao bạn không thử? Và phần nào của tài liệu khiến bạn nghĩ rằng nó sẽ làm điều đó? – TomTom

+1

Phần này: * Theo mặc định, thao tác sao chép số lượng lớn là giao dịch của chính nó * nhưng sau đó nó cũng cho biết * Thao tác sao chép hàng loạt diễn ra theo cách không giao dịch, không có cơ hội để quay lại * vì vậy ... đó là loại gây nhầm lẫn – Dan

+0

Kiểm tra chỉnh sửa. – mybirthname

Trả lời

25

Không ở đây là văn bản từ SqlBulkCopy tài liệu trong msdn

Theo mặc định, một hoạt động sao chép số lượng lớn được thực hiện như một hoạt động cô lập. Thao tác sao chép số lượng lớn xảy ra theo cách không giao dịch, mà không có cơ hội để quay lại. Nếu bạn cần khôi phục tất cả hoặc một phần của bản sao hàng loạt khi xảy ra lỗi, bạn có thể sử dụng Giao dịch được quản lý bởi SqlBulkCopy, thực hiện thao tác sao chép số lớn trong giao dịch hiện tại hoặc được tham gia vào một hệ thống giao dịch . Giao dịch.

EDIT: đọc đúng các tài liệu, từ liên kết mà tôi đã cho bạn:

Theo mặc định, một hoạt động sao chép số lượng lớn là giao dịch riêng của mình. Khi bạn muốn thực hiện thao tác sao chép hàng loạt chuyên dụng, hãy tạo một phiên bản mới của SqlBulkCopy bằng chuỗi kết nối hoặc sử dụng đối tượng SqlConnection hiện có
hiện tại mà không có giao dịch đang hoạt động.Trong mỗi trường hợp , thao tác sao chép hàng loạt sẽ tạo và sau đó cam kết hoặc cuộn quay lại giao dịch.

Điều này được viết cho trường hợp giao dịch sao chép hàng loạt nội bộ, trong đó không phải là làm mặc định!

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
         connectionString, SqlBulkCopyOptions.KeepIdentity | 
         SqlBulkCopyOptions.UseInternalTransaction)) 
    { 
     .... 
    } 

Xem kỹ trong SqlBulkCopyOptions.UseInternalTransaction! Bạn rõ ràng chỉ định tùy chọn UseInternalTransaction trong hàm tạo lớp SqlBulkCopy để rõ ràng gây ra một hoạt động sao chép hàng loạt để thực thi trong giao dịch riêng của mình, khiến cho mỗi lô hoạt động sao chép số lượng lớn thực thi trong một giao dịch riêng biệt. , nếu xảy ra lỗi trong quá trình sao chép hàng loạt, tất cả các hàng trong lô hiện tại sẽ được cuộn lại, nhưng các hàng từ các lô trước đó sẽ vẫn còn trong cơ sở dữ liệu.


Nếu bạn cần phải quay trở lại toàn bộ hoạt động sao chép số lượng lớn vì một lỗi xảy ra, hoặc nếu bản sao số lượng lớn nên thực hiện như một phần của một quá trình lớn hơn có thể được cuộn lại, bạn có thể cung cấp một đối tượng SqlTransaction đến hàm tạo SqlBulkCopy.

Trường hợp giao dịch bên ngoài.

  using (SqlTransaction transaction = 
         destinationConnection.BeginTransaction()) 
      { 
       using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
          destinationConnection, SqlBulkCopyOptions.KeepIdentity, 
          transaction)) 
       { 
        .... 
       } 
      } 

Như tôi đã nói ở cầu xin câu trả lời là không, bạn nên sử dụng giao dịch hiện có hoặc giao dịch với số lượng lớn bản sao nội. Đọc tệp tài liệu có trong liên kết, để biết thêm thông tin.

Nếu bạn muốn có giao dịch, bạn nên sử dụng một trong hai trường hợp mà tôi đã viết.

+0

Nó nói trong các tài liệu đó: * Theo mặc định, hoạt động sao chép hàng loạt là giao dịch của riêng nó. Khi bạn muốn thực hiện một thao tác sao chép hàng loạt chuyên dụng, hãy tạo một cá thể mới của SqlBulkCopy với một chuỗi kết nối, hoặc sử dụng một đối tượng SqlConnection hiện có mà không có một giao dịch hoạt động. Trong mỗi kịch bản, thao tác sao chép hàng loạt tạo ra, và sau đó cam kết hoặc cuộn lại giao dịch. * Điều đó có nghĩa là nếu tôi sử dụng 'using (SqlBulkCopy bulkCopy = new SqlBulkCopy (kết nối))' thay vì những gì tôi có, thì nó sẽ là trong một giao dịch? Hoặc là tốt hơn để gọi 'con.BeginTransaction' bản thân mình? – Dan

+0

@Dan kiểm tra chỉnh sửa và cho tôi biết nếu có điều gì đó không rõ ràng! – mybirthname

+1

Cảm ơn, điều đó rõ ràng. – Dan

Các vấn đề liên quan