[英]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.