任务,TransactionScope和SQL Server存储过程
本文关键字:Server 存储过程 SQL TransactionScope 任务 | 更新日期: 2023-09-27 18:07:37
我必须更新一些DataTable,我将其作为XML发送数据。我的存储过程具有事务,以便在出现问题时中止操作。但是我必须更新的记录数量非常大,XML达到了35 mb以上。它还处于开发阶段,实时数据将会更大。
为了处理这个问题,我想通过发送数据块来更新,也就是说,我将一次发送几百条记录的XML。我尝试使用Task
库像这样并行地更新数据库。
var ret=0;
using(var ts = new TransactionScope(TransactionScopeOption.Required,
new TimeSpan(2,0,0))
{
try
{
for(some condition)
{
get chunk of records
generate xml
create new task and call routing to push data to db
var t = create new task and call routing to push data to db
tasks.Add(t);
}
Task.WaitAll(tasks.ToArray());
ts.Complete();
foreach(var t in tasks)
ret += t.Result;
}
catch(Exception ex)
{
//log exception and show user message
}
}
return ret;
但是我得到的异常是事务已经中止。
我要做的是在单个事务中完成更新,因为如果任何块不能正确更新,我必须回滚任何更改。
编辑:-我使用new TransactionScope(TransactionScopeOption.Required,new TimeSpan(2,0,0))
如Reed Copsey所建议的,但仍然得到错误 System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.TimeoutException: Transaction Timeout
即使在一个调用数据库后,在2-3秒内完成。
只能调用一次
请等待任务完成后再调用ts.Complete()
。这看起来应该更像:
using(var ts = new TransactionScope())
{
try
{
List<Task> tasks = new List<Task>();
for(some condition)
{
// get chunk of records
// generate xml
// create new task and call routing to push data to db
var task = PushDataAsync(theData); // make the task
tasks.Add(task); // Keep a reference in a collection
}
// Wait until all tasks are done, so you can complete the transaction...
// If any task raises an exception, you'll get an AggregateException here
Task.WaitAll(tasks.ToArray());
ts.Complete();
}
catch(Exception ex)
{
//log exception and show user message
}
}
你考虑过线程安全吗?我想知道pushdatasync里面有什么。
TransactionScope不能跨线程工作。它在内部使用线程本地存储。作用域属于单个线程的事实在文档中被显式地调用。
不确定你是否真的走在正确的方向,但看看DependentTransaction,如果你想协调跨多个线程的事务:http://msdn.microsoft.com/en-us/library/system.transactions.dependenttransaction.aspx