【发布时间】:2014-06-06 14:33:25
【问题描述】:
Parallel.Invoke() 中有多个需要在事务内部运行的方法。这些方法都调用SqlBulkCopy 的实例。用例是“all-or-none”,因此如果一个方法失败,则不会提交任何内容。当我在父事务上调用 Complete() 方法时,我得到了 TransactionAbortedException ({"Transaction Timeout"})。
这是父事务:
using (var ts = new TransactionScope())
{
var saveClone = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
var saveErrorsClone = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
var saveADClone = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
var saveEnrollmentsClone = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
Parallel.Invoke(_options, () =>
{
Save(data, saveClone);
},
() =>
{
SaveErrors(saveErrorsClone);
},
() =>
{
SaveEnrollments(data, saveEnrollmentsClone);
});
ts.Complete();
}//***** GET THE EXCEPTION HERE *****
这是一个使用 SqlBulkCopy 的依赖事务(它们都是相同的结构)。我正在传入父母并将其分配给孩子的TransactionScope
private void Save(IDictionary<string, string> data, Transaction transaction)
{
var dTs = (DependentTransaction)transaction;
if (transaction.TransactionInformation.Status != TransactionStatus.Aborted)
{
using (var ts = new TransactionScope(dTs))
{
_walmartData.Save(data);
Debug.WriteLine("Completed Processing XML - {0}", _stopWatch.Elapsed);
ts.Complete();
}
}
else
{
Debug.WriteLine("Save Not Executed - Transaction Aborted - {0}", _stopWatch.Elapsed);
dTs.Complete();
}
dTs.Complete();
}
编辑(添加了我的SqlBulkCopy 方法...注意事务参数为空)
private void SqlBulkCopy(DataTable dt, SqlBulkCopyColumnMappingCollection mappings)
{
try
{
using (var sbc = new SqlBulkCopy(_conn, SqlBulkCopyOptions.TableLock, null))
{
sbc.BatchSize = 100;
sbc.BulkCopyTimeout = 0;
sbc.DestinationTableName = dt.TableName;
foreach (SqlBulkCopyColumnMapping mapping in mappings)
{
sbc.ColumnMappings.Add(mapping);
}
sbc.WriteToServer(dt);
}
}
catch (Exception)
{
throw;
}
}
除了修复错误之外,我还愿意接受替代方案。谢谢。
【问题讨论】:
-
您的并行调用是顺序的...
-
@usr...谢谢,我更新了代码。
标签: c# multithreading task-parallel-library transactionscope sqlbulkcopy