【问题标题】:Using TransactionScope to perform select使用 TransactionScope 执行选择
【发布时间】:2016-07-18 13:38:41
【问题描述】:

我看到我公司的很多人都在这样做:

var transactionOptions = new System.Transactions.TransactionOptions();
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;

using (var transactionScope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, transactionOptions))
{
    try
    {
        using (DefaultContext ctx = new DefaultContext())
        {
            return ctx.Item.Where(x => x.State == 1);
        }
    }
    catch (Exception err)
    {
        throw err;
    }
    finally
    {
        transactionScope.Complete();
    }
}

我真的需要打开一个事务到一个 Select 并调用 Complete() 方法吗?我以为它只是为了数据修改......

如果正确,有人可以向我解释一下吗?这是一个好习惯还是坏习惯?不需要吗?

谢谢

【问题讨论】:

  • 这似乎完全没有必要。它可能运行得很快,但我不会产生开销。我只使用带有插入和更新的作用域 txns。我看到这确实将IsolationLevel 设置为ReadUncommitted。他们这样做可能是为了提供 NOLOCK 效果。
  • ReadUncommitted 允许脏读,这意味着您可能会在读取中看到来自未提交查询的数据(请参阅stackoverflow.com/questions/2471055/…),这不是默认设置,但catch/throw 构造是完全没有必要的。
  • 您问过贵公司的任何人为什么要这样做吗? ;) 我同意@R。理查兹,在我看来,这样做的唯一原因是使用未提交的读取隔离级别。这表明存在(或在某些时候存在)一些锁定问题正在/正在阻碍应用程序,因此 ReadUncommitted 用于避免获取读取锁定。 IMO,这是一个相当大的数据访问更改(全面使用),所以我希望有人知道完整的故事。或者也许一个人曾经这样做过,现在这是一个复制/粘贴问题。

标签: c# sql-server entity-framework transactions repository-pattern


【解决方案1】:

因此,如果您要对数据库做很多事情,那么事务范围的用途是什么。所以说你正在修改 3 个表。您修改了表 1、表 2,但是当您尝试修改表 3 时它失败了。如果第三次失败,您不希望保留在表 1 和 2 中所做的更改。这是您将其包装在事务范围内的地方,因为如果出现错误,所有这些更改都会回滚(或者说不接受),您不必担心。

您可以阅读更多here

将查询包装在事务范围内只是为了获取数据......我没有看到任何好处。您是对的,没有数据操作,因此实际上不必有事务范围。我假设您的一些同事刚刚看到其他人使用了一个,并决定如果他们也这样做是个好主意。

另一个奇怪的事实是他们在 finally 中完成了事务范围。如果出现错误,您可能不想完成交易。

【讨论】:

  • 你说得对。他们只是复制并过去了项目中每个代码块的事务......“他们没有时间问为什么”。你的回答很有帮助,伙计。谢谢!
猜你喜欢
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
相关资源
最近更新 更多