【问题标题】:C# nested transactionsC# 嵌套事务
【发布时间】:2015-01-15 12:28:16
【问题描述】:

我对下面显示的代码有疑问。

try
{
     using (TransactionScope outerTransScope = new TransactionScope(TransactionScopeOption.RequiresNew))
     {
          // 1.Change values in certain columns from the SQL database table

          using (TransactionScope innerTransScope = new TransactionScope(TransactionScopeOption.RequiresNew))
          {
               // 2.Update a column from the SQL database table by using the changed values from the outerTransScope as a JOIN condition.

               // 3.Commit the update query
               innerTransScope.Complete();
          }
     }
     // 4.Rollback the changed values that were executed in the outerTransScope
}
catch (Exception)
{
// Log the exception
}

我是否正确地说这不会像我预期的那样工作?由于outerTransScope实际上是在回滚innerTransScope,因为我从未提交outerTransScope。

这意味着您只能在根事务最后提交的情况下提交嵌套事务。如果根事务未提交,那么即使您提交了内部事务,所有嵌套事务也会回滚。

是否有可能获得上面代码中显示的功能?提前致谢。

编辑: 假设我们有两个表,表 A 和表 B。

Table A:                         Table B:
Column A | Column B              Column A | Column B
Siemens  | 100                   SIE      | null
Siemens  | 101                   SIE      | null
Siemens  | 102                   SIE      | null
Siemens  | 103                   SIE      | null

我想用表 A 中的 B 列更新表 B 中的 B 列,但是我只想在表 A 中的 A 列和表 B 中的 A 列 100% 匹配时执行此操作。现在什么都不会发生,因为表 A 中的 A 列不等于表 B 中的 A 列。

因此,为了解决这个问题,用户可以使用我称之为操作方案的东西来编辑列。此操作方案将在表 A 中将 'Siemens' 替换为 'SIE'。当此操作被替换时,表 A 中的 A 列等于表 B 中的 A 列。通过此匹配,我现在可以使用 B 列中的值更新表 B 中的 B 列来自表 A。当此更新完成后,我想提交这些更改并回滚我在表 A 中对列 A 所做的编辑(必须回滚“Siemens”更改为“SIE”)。

在我的代码中,它看起来像这样:

try
{
    using (TransactionScope outerTransScope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
          // 1.Change Siemens into SIE Column A from Table A
              using (TransactionScope innerTransScope = new TransactionScope(TransactionScopeOption.RequiresNew))

          {
               // 2.Update Column B from Table B with the values of Column B from Table B, but only if Column A from Table A equals Column A from Table B. 

               // 3.Commit the update of Column B from Table B
               innerTransScope.Complete();
          }
     }
     // 4.Rollback the changes in Column A from Table A (So SIE becomes Siemens again).
}
catch (Exception)
{
// Log the exception
}

【问题讨论】:

  • 当您出于测试目的运行此程序时(我假设您这样做了);你发现了什么?
  • 无法通过 ADO.NET 和 SQL Server 2005+ 创建嵌套事务:stackoverflow.com/questions/16214589/…
  • 事务语句应该存储在数据库中而不是客户端。如果您创建存储过程来处理此问题,您将拥有更好的灵活性。
  • TransactionScopeOption.RequiresNew 使内部事务独立于外部事务,因此将立即提交,而不是等待外部事务提交或回滚。但是,您使用 SqlServer 的情况可能会有所不同,具体取决于支持的内容。您可能需要在内部事务中打开新连接。

标签: c# sql-server


【解决方案1】:

我可以按要求回答问题,但这只是个坏主意。您在这里尝试做的事情会遇到许多问题,例如事务之间的隔离和事务之间的分布式死锁。 SQL Server 无法解决分布式死锁。它们在 30 秒超时后得到解决。

这是一个脆弱的方案。

找到一种不需要回滚任何东西的方法。例如,在临时表中创建临时数据并使用它。使用单个事务和单个连接。

【讨论】:

    【解决方案2】:

    在嵌套事务中,没有任何事务层次结构。它总是只有一个交易。您只能使用TransactionScopeOption.Required 创建事务的依赖关系,这样它将使用现有的可用事务并加入它。您正在为某个目的创建依赖项。如果你不想要依赖,那么首先完成初始事务处理它,然后创建新范围并完成它。

    【讨论】:

      猜你喜欢
      • 2015-08-26
      • 2016-09-09
      • 2014-12-12
      • 2016-09-10
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      相关资源
      最近更新 更多