任务,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秒内完成。

只能调用一次

任务,TransactionScope和SQL Server存储过程

请等待任务完成后再调用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