基于接受的答案更新:
bool success = false;
using (var bulkCopy = new SqlBulkCopy(connection)) //using!
{
connection.Open();
//explicit isolation level is best-practice
using (var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted))
{
bulkCopy.DestinationTableName = "table";
bulkCopy.ColumnMappings...
using (var dataReader = new ObjectDataReader<SomeObject>(paths))
{
bulkCopy.WriteToServer(dataReader);
success = true;
}
tran.Commit(); //commit, will not be called if exception escapes
}
}
return success;我将BulkCopy类用于大型insert,它工作得很好。
执行WriteToServer并将数据保存到数据库后
我不想知道是否所有的数据都保存成功了,所以我可以返回true/false,因为我需要保存所有或什么都不保存?
var bulkCopy = new SqlBulkCopy(connection);
bulkCopy.DestinationTableName = "table";
bulkCopy.ColumnMappings...
using (var dataReader = new ObjectDataReader<SomeObject>(paths))
{
try
{
bulkCopy.WriteToServer(dataReader);
}
catch(Exception ex){ ... }
}发布于 2013-10-01 11:37:49
如果没有异常地完成对WriteToServer的调用,则所有行都已保存并位于磁盘上。这只是Server的标准语义。批量复制没有什么特别之处。
和所有其他的DML一样,SqlBulkCopy也是什么都不是。除非您配置了未配置的批处理大小。
using (var bulkCopy = new SqlBulkCopy(connection)) //using!
{
connection.Open();
//explicit isolation level is best-practice
using (var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted))
{
bulkCopy.DestinationTableName = "table";
bulkCopy.ColumnMappings...
using (var dataReader = new ObjectDataReader<SomeObject>(paths))
{
//try
//{
bulkCopy.WriteToServer(dataReader, /*here you set some options*/);
//}
//catch(Exception ex){ ... } //you need no explicit try-catch here
}
tran.Commit(); //commit, will not be called if exception escapes
}
}我已经添加了与最佳实践相一致的示例代码。
发布于 2013-10-01 11:21:16
除了查找/捕获WriteToServer()方法引发的任何异常之外,没有任何直接的方法来识别流程是否成功完成。
另一种方法可能是检查数据库中的记录数,然后在进程完成后检查记录的数量--不同的是插入的数量。将此值与要插入的记录数进行比较,可以给出失败或成功的概念。然而,这并不是愚蠢的证明,特别是如果有其他进程插入/删除记录。
然而,这些技术结合TransactionScope - http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx -或类似的技术应该可以实现您所需要的。
编辑
默认情况下,每个insert操作都作为批处理处理;如果操作在特定批处理中失败,则该批处理将回滚,而不是在其之前插入。
但是,如果将内部事务应用于大容量操作而不是中的失败,则任何行都可以回滚整个结果集。例如;
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(connectionString, SqlBulkCopyOptions.KeepIdentity
| SqlBulkCopyOptions.UseInternalTransaction))
{
bulkCopy.BatchSize = 10;
bulkCopy.DestinationTableName = "dbo.BulkCopyDemoMatchingColumns";
try
{
bulkCopy.WriteToServer(reader);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
bulkCopy.Close();
}
}上述操作中的任何一个错误都会导致整个操作回滚。请在http://msdn.microsoft.com/en-us/library/tchktcdk.aspx上查看有关此问题的更多详细信息。
发布于 2013-10-01 11:15:56
从这个函数的文档中,下面的片段建议您捕获抛出的任何异常,否则您可以认为操作是成功的。
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
{
bulkCopy.DestinationTableName = "dbo.BulkCopyDemoMatchingColumns";
try
{
// Write from the source to the destination.
bulkCopy.WriteToServer(reader);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// Close the SqlDataReader. The SqlBulkCopy
// object is automatically closed at the end
// of the using block.
reader.Close();
}
}如果您想要确定,在大容量复制完成后,对数据库执行一个查询以检查行是否在那里。
https://stackoverflow.com/questions/19114696
复制相似问题