我通过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);
}
}
我发现docs在这个问题上有点不清楚,因为他们最初陈述
默认情况下,批量复制操作作为隔离执行 操作。批量复制操作以非事务方式发生, 没有机会回滚
但稍后才说明
默认情况下,批量复制操作是自己的事务。当你 想要执行专用的批量复制操作,创建一个新实例 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();
}
}
}
答案 0 :(得分:35)
此处msdn
中的SqlBulkCopy
文档中的文字不存在
默认情况下,批量复制操作作为隔离执行 操作。 批量复制操作以非事务方式发生, 没有机会回滚。如果你需要回滚所有 或发生错误时批量复制的一部分,您可以使用 SqlBulkCopy管理的事务,执行批量复制操作 在现有交易中,或被征募入 System.Transactions Transaction。
修改强> 从我给你的链接中正确阅读文档:
默认情况下,批量复制操作是自己的事务。当你 想要执行专用的批量复制操作,创建一个新的 带有连接字符串的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))
{
....
}
}
就像我在乞讨中所说的那样,答案是否定的,你应该使用现有的交易或内部批量复制交易。有关详细信息,请阅读链接中的文档文件。
如果你想要交易,你应该使用我写的两个案例中的一个。