【问题标题】:Downside of using TransactionScope RequiresNew使用 TransactionScope RequiresNew 的缺点
【发布时间】:2011-04-22 22:10:32
【问题描述】:

我想了解在 EntityFrameworkw/Sql Server 2008)上使用 TransactionScopeOption.RequiresNew 的权衡/缺点是什么,我们为什么要这样做?不应该总是使用RequiresNew

问候。

【问题讨论】:

    标签: c# .net sql entity-framework


    【解决方案1】:

    您应该使用Required 而不是RequiresNew。 RequiresNew 意味着每个操作都将使用一个新事务,即使已经存在一个包含的事务范围。这肯定会导致死锁。即使使用RequiredTransactionScope 也存在另一个严重问题,即默认情况下它会创建一个Serializable 事务,这是一个非常糟糕的选择,并且是另一个通往死锁地狱且没有可扩展性的捷径。见using new TransactionScope() Considered Harmful。您应该始终使用显式的TransactionOption 将隔离级别设置为ReadCommitted 创建一个事务范围,这是一个更加合理的隔离级别:

    using(TransactionScope scope = new TransactionScope(
        TransactionScopeOption.Required,
        new TransactionOptions {
           IsolationLevel = IsolationLevel.ReadCommitted}))
    {
       /// do work here
       ...
       scope.Complete();
    }
    

    【讨论】:

    • 感谢您的回答!那我们什么时候应该使用RequiresNew呢?
    • RequiresNew 在您想要独立事务时使用,而不是调用上下文事务的一部分。换句话说,从不
    • 有时RequiresNew 对日志记录或审计很有用,无论包含事务如何都应该成功。我同意,使用前请慎重考虑。
    • @BrianLow:但是除非您的日志记录/审计代码使用IEnlistmentNotification,否则它不会在外部事务失败时始终记录并且永远不会回滚吗?
    • RequiresNew 不应用于隔离日志记录/审计与可能中止事务,如果说日志记录代码抛出异常,这就是 TransactionScope.Suppress 明确设计的目的。
    【解决方案2】:

    我只是想在这里补充一点,在某些情况下,我编写的方法位于父事务范围内,在这些情况下我不想依赖于 scope.Complete() 可能会或可能不会关闭父事务,所以我们需要设置 RequiresNew。

    虽然我同意一般来说没有必要,但应该使用已提交的读取。

    http://msdn.microsoft.com/en-us/library/ms172152(v=vs.90).aspx

    【讨论】:

      猜你喜欢
      • 2011-06-05
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 2013-12-02
      • 2020-05-12
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多