簡體   English   中英

SqlBulkCopy會自動啟動事務嗎?

[英]Does SqlBulkCopy automatically start a transaction?

我通過SqlBulkCopy插入數據,如下所示:

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);
        }
    }
}

這會自動包裝在SQL事務中,這樣如果出現問題,數據庫的一半將保持與批量插入開始之前相同的狀態嗎? 或者將插入一半的數據?

即我是否有必要明確調用con.BeginTransaction

或者如果我調用SqlBulkCopy的構造函數來獲取字符串,那么這是一種更好的方法來使它在事務中發生嗎?

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

我發現這個問題的文檔有點不清楚,因為他們最初表明了這一點

默認情況下,批量復制操作作為隔離操作執行。 批量復制操作以非事務方式發生,沒有機會將其回滾

但后來說明了

默認情況下,批量復制操作是其自己的事務。 如果要執行專用批量復制操作,請使用連接字符串創建SqlBulkCopy的新實例,或使用不帶活動事務的現有SqlConnection對象。 在每個方案中,批量復制操作都會創建,然后提交或回滾事務。

所以有必要這樣做:

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();
        }
    }
}

這里沒有來自msdn中 SqlBulkCopy文檔的文本

默認情況下,批量復制操作作為隔離操作執行。 批量復制操作以非事務方式發生,沒有機會將其回滾。 如果在發生錯誤時需要回滾全部或部分批量復制,則可以使用SqlBulkCopy管理的事務 ,在現有事務中執行批量復制操作,或者在System.Transactions事務中登記。

編輯:從我給你的鏈接中正確閱讀文檔:

默認情況下,批量復制操作是其自己的事務。 如果要執行專用批量復制操作,請使用連接字符串創建SqlBulkCopy的新實例,或使用
沒有活動事務的現有SqlConnection對象。 在每個方案中,批量復制操作都會創建,然后提交或回滾事務。

這是針對案例內部批量復制事務編寫的,這不是默認值!

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

仔細查看SqlBulkCopyOptions.UseInternalTransaction 您在SqlBulkCopy類構造函數中顯式指定UseInternalTransaction選項,以顯式地使批量復制操作在其自己的事務中執行,從而導致每批批量復制操作在單獨的事務中執行。因為不同的批處理在不同的事務中執行,如果在批量復制操作期間發生錯誤,則將回滾當前批次中的所有行,但以前批次中的行將保留在數據庫中。


如果由於發生錯誤而需要回滾整個批量復制操作,或者如果批量復制應作為可以回滾的較大進程的一部分執行,則可以向SqlBulkCopy構造函數提供SqlTransaction對象。

外部交易案例。

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

就像我在乞討中說的那樣,答案是否定的,你應該使用現有的交易或內部批量復制交易。 有關詳細信息,請閱讀鏈接中的文檔文件。

如果你想要交易,你應該使用我寫的兩個案例之一。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM