【问题标题】:ADO.NET Isolation Level v TransactionScope isolation levelADO.NET 隔离级别 v TransactionScope 隔离级别
【发布时间】:2013-07-26 07:04:20
【问题描述】:

我读过 ADO.NET 的默认隔离级别(当不使用事务时,即每个语句都作为原子操作执行)是“READ COMMITTED”,而 TransactionScope (http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx) 的默认隔离级别是“可序列化”。这是有原因的吗?

我已经阅读了很多关于这个主题的网页,但我还没有找到我的具体问题的答案。

【问题讨论】:

    标签: .net transactions


    【解决方案1】:

    事务是一个工作单元,基本上意味着在该范围内执行了多个活动。例如,预订购物车涉及检查产品、检查现有数量、计算运费和更新财务账户。所有这些操作都应该是一个或没有,如果它们中的任何一个有一个幻读,就像在隔离级别 'READ COMMITTED' 的情况下,那么它会将数据置于陈旧状态。如果使用 'SERIALIZED' 范围,那么它将阻止对事务中涉及的实体进行任何更新。

    如果您查看一个月的财务报告,则 'READ COMMITTED' 隔离级别有效,因为您查看的是现有数据并且没有进行太多修改,甚至是幻像读取不会在报告中产生太大差异。

    【讨论】:

    • 谢谢,但我不相信这能回答我的问题。我了解所讨论的两种隔离类型之间的区别。我想知道为什么 TransactionScope 默认情况下与 SQL Server 相比具有不同的隔离级别。
    • 好吧,默认情况下,任何 RDBMS 解决方案都支持 ACID 属性。默认情况下,如果没有事务范围,它将是 READ COMMITTED。希望我回答了你的问题。
    • 您知道隔离级别是否可以通过 transactionscope 序列化是有原因的吗?我怀疑这只是 transactionscope 开发人员做出的设计决定。
    • 想一想,任何设计都基于您可能知道的用例。在单个事务中,如果您需要控制,那么对于单个表来说它是 READ COMMITTED 可以工作,但是如果您需要支持更新多个表并确保它满足 ACID 属性怎么办。然后你需要 TransactionScope。只是隔离级别的另一个名称来区分,因为你不能在相同的隔离级别上做所有事情。
    • 再次感谢。你是说在更新多个表时应该始终使用可序列化的隔离级别?
    【解决方案2】:

    原因是事务范围可以跨越多个(子)事务,这些事务都与分布式事务协调器 (MS-DTC) 进行协调。大多数情况下,您需要确保所有子事务都使用相同的数据,即使它们之间发生了提交。

    例如一个有 3 种方法的服务:checkbalance、increasbalance 和 reductionbalance。 每个方法启动一个事务,打开一个数据库连接,执行一条 SQL,关闭连接并提交事务。

    一个典型的场景是这个服务的客户:

    1. 开始主事务
    2. 查看账户 1 的余额
    3. 减少账户 1 的余额
    4. 增加账户 2 的余额
    5. 提交主事务

    IsolationLevel.Serializable 将确保所有服务调用将 a) 从相同的数据开始,并且 b) 在主事务运行时不允许其他任何人更改该数据。

    IsolationLevel.ReadCommitted 可能会导致账户 1 的余额低于零,如果其他人减少了足够的余额并在支票和减少之间提交了该交易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-04
      • 2015-08-02
      • 2013-01-25
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多