【问题标题】:Commiting inner transaction scope, while rolling back the outer transaction scope提交内部事务范围,同时回滚外部事务范围
【发布时间】:2013-03-07 18:52:59
【问题描述】:

我正在尝试在用 C# 编写的高并发系统中执行以下操作。

  1. 获取事务范围内数据项的行锁
  2. 做大量的数据库交互
  3. 如果出现任何问题
    • 更新锁定的数据项,处理失败
    • 提交更新
    • 回滚第 2 步中的任何更改并解除对数据项的锁定

但是 - 我不知道如何实现这一点,而不是在更新之前释放项目锁定。我目前的(坏的)解决方案是这样的:

  1. 获取事务范围内数据项的行锁
  2. 做大量的数据库交互
  3. 如果出现任何问题
    • 回滚第 2 步中的任何更改并解除对数据项的锁定
    • 在新事务范围内重新获取数据项锁定
    • 更新锁定的数据项,处理失败
    • 提交更新

此解决方案的问题在于,我释放了锁,以便另一个进程可以在我更改写入处理失败的项目之前获取该项目。

有没有办法创建一个嵌套事务范围,它可以提交被外部事务范围锁定的项目,同时仍然允许外部范围回滚?

看来我所有的麻烦都来自这样一个事实,即外部范围锁定了内部范围要更新的项目。

【问题讨论】:

标签: c# sql database transactions transactionscope


【解决方案1】:

按照我对问题的理解,你所要求的是不可能的。

有什么东西阻止你使用类似的模式吗?

begin outer transaction

  //do some stuff

  bool failedFlag = false;

  begin inner transaction

    // do some more stuff

    if (failed)
      failedFlag = true
      roll back inner transaction
    else
      commit inner transaction
  end inner

  if (failedFlag)
    update locked items with failed status

commit outer transaction

【讨论】:

  • 因此,如果我理解您的代码正确,您将让外部作用域锁定并对锁定的项目进行任何更新。虽然内部范围可以独立于外部范围提交和回滚,但是否对数据库执行所有不涉及锁定行的操作?
  • 是的,我想这就是我的意思;)一个澄清:内部范围不能真正“独立于外部范围的提交和回滚” - 它在语义上是嵌套的,所以如果外部事务回滚内部与它一起回滚。 OTOH,如果内部回滚其更改,外部事务仍然可以提交在内部范围之外进行的更改。
猜你喜欢
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多