Dan*_*Dan 19 c# sql-server transactions bulkinsert sqlbulkcopy
我通过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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这会自动包装在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);
}
}
Run Code Online (Sandbox Code Playgroud)
我发现这个问题的文档有点不清楚,因为他们最初表明了这一点
默认情况下,批量复制操作作为隔离操作执行.批量复制操作以非事务方式发生,没有机会将其回滚
但后来说明了
默认情况下,批量复制操作是其自己的事务.如果要执行专用批量复制操作,请使用连接字符串创建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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
myb*_*ame 40
这里没有来自msdnSqlBulkCopy文档的文本
默认情况下,批量复制操作作为隔离操作执行.批量复制操作以非事务方式发生,没有机会将其回滚.如果在发生错误时需要回滚全部或部分批量复制,则可以使用SqlBulkCopy管理的事务,在现有事务中执行批量复制操作,或者在System.Transactions事务中登记.
编辑: 从我给你的链接中正确阅读文档:
默认情况下,批量复制操作是其自己的事务.如果要执行专用批量复制操作,请使用连接字符串创建SqlBulkCopy的新实例,或使用
不带活动事务的现有SqlConnection对象.在每个方案中,批量复制操作都会创建,然后提交或回滚事务.
这是针对案例内部批量复制事务编写的,这不是默认值!
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
connectionString, SqlBulkCopyOptions.KeepIdentity |
SqlBulkCopyOptions.UseInternalTransaction))
{
....
}
Run Code Online (Sandbox Code Playgroud)
仔细看看SqlBulkCopyOptions.UseInternalTransaction!您在SqlBulkCopy类构造函数中显式指定UseInternalTransaction选项,以显式地使批量复制操作在其自己的事务中执行,从而导致每批批量复制操作在单独的事务中执行.因为不同的批处理在不同的事务中执行,如果在批量复制操作期间发生错误,则将回滚当前批次中的所有行,但以前批次中的行将保留在数据库中.
如果由于发生错误而需要回滚整个批量复制操作,或者如果批量复制应作为可以回滚的较大进程的一部分执行,则可以向SqlBulkCopy构造函数提供SqlTransaction对象.
外部交易案例.
using (SqlTransaction transaction =
destinationConnection.BeginTransaction())
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
destinationConnection, SqlBulkCopyOptions.KeepIdentity,
transaction))
{
....
}
}
Run Code Online (Sandbox Code Playgroud)
就像我在乞讨中说的那样,答案是否定的,你应该使用现有的交易或内部批量复制交易.有关详细信息,请阅读链接中的文档文件.
如果你想要交易,你应该使用我写的两个案例之一.
| 归档时间: |
|
| 查看次数: |
15186 次 |
| 最近记录: |