C#和SQL Server:多线程,连接和事务

时间:2017-11-07 12:44:18

标签: c# sql-server multithreading transactions

我正在寻找棘手问题的解决方案。

我和我的同事制作了一个'引擎'(在C#中),它在SQL Server数据库上执行不同的详细说明。

最初,这些详细说明包含在夜间批处理系列中的许多存储过程中。这是一个有很多缺陷的系统。

现在我们已经从每个存储过程中提取了每个查询,并且可能听起来很奇怪,我们已经将查询插入到数据库中

(注意:原因不同而且我没有全部列出,但你只需要知道,出于商业原因,我们没有机会经常发布软件......但我们有很多SQL脚本的自由度。)

主要是,我们的引擎背后的逻辑是:

  • 阶段,顺序调用
  • 每个阶段包含多个步骤,然后细分为设置
  • Set是一组将按顺序执行的步骤
  • 除非另有说明,否则启动彼此并行运行
  • 默认情况下不属于任何Set的步骤将嵌入Set(在运行时创建)
  • 启动前的设置可能需要等待一个或多个步骤的完成
  • Step对应于原子(或几乎)SQL查询或C#方法来运行
  • 启动时引擎查询数据库,然后编写阶段,步骤和设置(及相关配置)......将执行

enter image description here

我们已经创建了引擎,我们拥有所有配置......一切正常。

但是,我们需要:某些阶段必须有交易。如果即使该阶段的一个步骤失败,我们也需要回滚整个阶段。

造成问题的是交易管理。

最初我们为整个阶段创建了一个事务和连接,但我们很快意识到 - 由于多线程 - 这不是线程安全的。

此外,经过多次测试,我们对交易有例外。显然,当一个阶段包含很多步骤(=许多数据库查询)时,同一个事务不能执行任何进一步的语句。

所以,现在,我们做了一些更改并确保需要事务的阶段中的每个步骤都会自行打开连接和事务,如果一切顺利,所有提交(否则回滚)。

有效。但是,我们注意到了一个限制:使用临时表

在事务阶段,当我在步骤x中创建临时临时表(#TempTable1)时,我无法在下一步y(#TempTable1)中使用SELECT TOP 1 1 FROM #TempTable1

这是合乎逻辑的:因为它是一个单独的事务,并且在执行实例的末尾删除了#TempTable1

然后我们尝试使用全局临时表##TempTable2,但是,在步骤y中,SELECT的执行被阻止,直到超时通过..

我也尝试降低事务隔离级别,但没有。

现在我们处于不幸的情况,不得不创建真正的表而不是使用临时表。

我正在寻找在大量步骤上使用事务和使用临时表之间的妥协。我认为演讲的重点是交易管理。建议?

0 个答案:

没有答案