Tsql 是否可以将DependentTransaction或多个DependentTransaction与TPL/并行性一起使用?
我还没有找到任何与我正在做的事情有点类似的东西,出于预算方面的考虑,我不得不向大家寻求帮助。我目前正在编写一个导入应用程序,可以导入数量可变的记录。更可能的是,这一可变数字将非常高,可能达到数百万。我们利用WCF流将数据块发送到服务器进行处理。在服务器端,我们将数据转储到临时SQL表中进行验证。在此基础上,使用TPL提取一组记录,然后将它们插入到永久SQL存储库中。其中涉及的内容很多,但简而言之,这是其中的主要部分。目前唯一悬而未决的问题是,我们允许用户随时取消导入。这意味着在保存这些记录的过程中可能会发生取消。我们需要能够回滚所有插入/更新的记录。由于我们使用TPL来处理记录,因此我在分享交易时遇到了极大的困难。我正在使用MSDN中概述的DependentTransaction方法(非常类似,)。以下是一些代码片段:Tsql 是否可以将DependentTransaction或多个DependentTransaction与TPL/并行性一起使用?,tsql,sql-server-2008,c#-4.0,transactions,parallel-processing,Tsql,Sql Server 2008,C# 4.0,Transactions,Parallel Processing,我还没有找到任何与我正在做的事情有点类似的东西,出于预算方面的考虑,我不得不向大家寻求帮助。我目前正在编写一个导入应用程序,可以导入数量可变的记录。更可能的是,这一可变数字将非常高,可能达到数百万。我们利用WCF流将数据块发送到服务器进行处理。在服务器端,我们将数据转储到临时SQL表中进行验证。在此基础上,使用TPL提取一组记录,然后将它们插入到永久SQL存储库中。其中涉及的内容很多,但简而言之,这是其中的主要部分。目前唯一悬而未决的问题是,我们允许用户随时取消导入。这意味着在保存这些记录的过程
var currentTransaction = System.Transactions.Transaction.Current;
在这个TPL迭代中,有许多选择、插入和更新。如果可能的话,我希望所有这些都发生在同一个事务下。或者至少可以通过TransactionScope进行管理,以便我们可以回滚所有内容。我不断得到“事务上下文已经在使用中”的错误,然后它几乎立即中止
我是否未正确使用DependentTransaction?我的要求可能吗?我知道事务通常是连续的,不在这种情况下使用,但为了简单起见,为了帮助我们不必实现一些疯狂的功能来跟踪插入的记录并手动回滚,事务将是理想的
有什么建议吗
注意:我尝试过使用局部状态方法来进行并行迭代,但无论我做什么,都会生成相同的异常。此外,使用RollbackIfNotComplete或BlockCommitUnitIlComplete与此无关。管理SQL Server事务的最佳位置是在T-SQL代码中。由于您已经在同一个SQL Server中拥有了所有要插入/更新/删除的数据,因此我认为没有任何理由不在t-SQL代码中的事务中执行选择/插入/更新。下面是一个简单的模板,您可以使用
-- REFERENCE: http://aleemkhan.wordpress.com/2006/07/21/t-sql-error-handling-pattern-for-nested-transactions-and-stored-procedures/
-- ======================================================================================
-- STANDARD HEADER FOR TRANSACTION LOGIC THAT WILL ALSO HANDLE BEING A NESTED TRANSACTION
-- FOR SQL 2005 AND UP
-- ======================================================================================
SET XACT_ABORT ON;
BEGIN TRY
DECLARE @TranStarted bit; SET @TranStarted = 0
IF( @@TRANCOUNT = 0 ) BEGIN BEGIN TRANSACTION; SET @TranStarted = 1; END ELSE SET @TranStarted = 0
-- ======================================================================================
-- ==================================================================
-- ***** SQL CODE FOR SELECTS/INSERTS/UPDATES/DELETES GOES HERE *****
-- ==================================================================
-- ======================================================================================
-- STANDARD FOOTER FOR TRANSACTION LOGIC THAT WILL ALSO HANDLE BEING A NESTED TRANSACTION
-- FOR SQL 2005 AND UP
-- ======================================================================================
IF( @TranStarted = 1 AND (XACT_STATE()) = 1 ) BEGIN SET @TranStarted = 0; COMMIT TRANSACTION; END
RETURN(0)
END TRY
BEGIN CATCH
DECLARE @ErrorMessage nvarchar(4000)
,@ErrorNumber int
,@ErrorSeverity int
,@ErrorState int;
SELECT @ErrorMessage = ERROR_MESSAGE() + CHAR(13) + 'Actual Code Line that took the error: ' + CONVERT(nvarchar, ERROR_LINE())
+ CHAR(13) + 'Actual Proc that took the error: ' + CONVERT(nvarchar(126), ERROR_PROCEDURE())
,@ErrorSeverity = ERROR_SEVERITY()
,@ErrorState = ERROR_STATE()
,@ErrorNumber = ERROR_NUMBER();
IF( @TranStarted = 1 AND (XACT_STATE()) = -1 ) BEGIN SET @TranStarted = 0; ROLLBACK TRANSACTION; END
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
-- ======================================================================================
我看过这篇文章()并且想知道这是否是不可能的。那篇文章大致概述了我正在努力做的事情。有人知道这是否发生了变化吗?记录被导入临时表。是否在导入完成之前开始处理(验证)临时表?在导入完成之前,您是否可以不开始处理?如果他们取消,则只需删除临时表即可。拥有数百万条记录的交易是一笔非常大的交易。您知道在事务完成之前,这些数据将是未提交的数据,并且需要大的事务日志吗?
-- REFERENCE: http://aleemkhan.wordpress.com/2006/07/21/t-sql-error-handling-pattern-for-nested-transactions-and-stored-procedures/
-- ======================================================================================
-- STANDARD HEADER FOR TRANSACTION LOGIC THAT WILL ALSO HANDLE BEING A NESTED TRANSACTION
-- FOR SQL 2005 AND UP
-- ======================================================================================
SET XACT_ABORT ON;
BEGIN TRY
DECLARE @TranStarted bit; SET @TranStarted = 0
IF( @@TRANCOUNT = 0 ) BEGIN BEGIN TRANSACTION; SET @TranStarted = 1; END ELSE SET @TranStarted = 0
-- ======================================================================================
-- ==================================================================
-- ***** SQL CODE FOR SELECTS/INSERTS/UPDATES/DELETES GOES HERE *****
-- ==================================================================
-- ======================================================================================
-- STANDARD FOOTER FOR TRANSACTION LOGIC THAT WILL ALSO HANDLE BEING A NESTED TRANSACTION
-- FOR SQL 2005 AND UP
-- ======================================================================================
IF( @TranStarted = 1 AND (XACT_STATE()) = 1 ) BEGIN SET @TranStarted = 0; COMMIT TRANSACTION; END
RETURN(0)
END TRY
BEGIN CATCH
DECLARE @ErrorMessage nvarchar(4000)
,@ErrorNumber int
,@ErrorSeverity int
,@ErrorState int;
SELECT @ErrorMessage = ERROR_MESSAGE() + CHAR(13) + 'Actual Code Line that took the error: ' + CONVERT(nvarchar, ERROR_LINE())
+ CHAR(13) + 'Actual Proc that took the error: ' + CONVERT(nvarchar(126), ERROR_PROCEDURE())
,@ErrorSeverity = ERROR_SEVERITY()
,@ErrorState = ERROR_STATE()
,@ErrorNumber = ERROR_NUMBER();
IF( @TranStarted = 1 AND (XACT_STATE()) = -1 ) BEGIN SET @TranStarted = 0; ROLLBACK TRANSACTION; END
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
-- ======================================================================================