【问题标题】:Transaction isolation level - choosing the right one事务隔离级别 - 选择正确的
【发布时间】:2014-01-11 14:39:22
【问题描述】:

我是 sql 初学者,我需要有关事务隔离级别的帮助。 我需要知道哪种隔离级别最适合以下情况以及原因:

数据库中有3张表:

  • 动物(通过在其中插入芯片进行注册)KEY - ID_CHIP REF CHIPS
  • 芯片(可以但不必插入动物体内)KEY - ID_CHIP。其中一个属性是“INSERTED_BY”,它引用第三个表 PEOPLE(给出插入芯片的人的 ID,如果尚未插入则为 NULL)
  • 人员 - 密钥:ID

现在让我们考虑以下交易:将新芯片插入动物体内。更新数据库的人必须改变两件事:

  • 向 ANIMALS 添加一个新实体
  • 更新插入的芯片记录(将 INSERTED_BY 属性从 NULL 更改为插入芯片的人的 ID)

第二个事务是控制器事务,它检查 ANIMALS 中的实体数量是否等于属性 INSERTED_BY 不等于 NULL 的 CHIPS 数量。 一种情况如下图所示:

谁能告诉我四个隔离级别中哪一个最好?为什么?我被困在这里.. 任何帮助将不胜感激。

【问题讨论】:

  • 你能解释一下为什么你需要第二次交易吗?读取索引/表堆中的所有记录不是一个好的/可扩展的解决方案。
  • @BogdanSahlean 这是一个学术项目,我必须模拟隔离级别,这就是我想出的例子。
  • @Simon 很高兴知道,因为这解释了为什么您对快照隔离不感兴趣。换句话说,您对生产级解决方案不感兴趣。你想精确地“模拟”什么?

标签: sql sql-server transactions isolation-level


【解决方案1】:

您的情况很简单,因为其中一个事务是纯读取事务。查看快照隔离。在SNAPSHOT 隔离级别下运行阅读器将为其提供整个数据库的时间点一致视图。不会占用或等待任何锁。

这意味着在 t2 时插入对 C2 不可见。

这很容易实现,完全解决了问题。

没有 SNAPSHOT 隔离,你需要SERIALIZABLE 隔离,你会死锁很多。现在您需要研究锁定提示。复杂得多,没有必要。

【讨论】:

  • 首先感谢您的宝贵时间!对不起,但我不明白。我可以选择:READ UNCOMMITED、READ COMMITED、REPEATABLE READ 和 SERIALIZABLE。哪个事务应该是 SERIALIZABLE 的,而第二个事务呢?为什么?
  • 首先,阅读快照隔离,了解它可以解决您的问题。这是一个非常好的工具。 google.com/…msdn.microsoft.com/en-us/library/tcbchxcb(v=vs.110).aspx 您可以使用 ADO.NET 和 SET TRANSACTION ISOLATION LEVEL SNAPSHOT.; C2 必须是可序列化的,以便事务的读取集被锁定(这将在您给出的计划中死锁,但至少它不会默默地返回错误结果)。
  • 谢谢,第二笔交易呢?
  • 没关系。写入将在任何隔离级别和任何类型的锁定提示下进行 X 锁定。我也会使用SERIALIZABLE,因为您似乎最关心的是安全。注意潜在的阻塞和死锁问题。另外,我再重复一遍:您的工作量以一定的概率陷入僵局。
  • @usr:你能告诉我这两个事务可以相互阻塞(死锁)的一种情况吗?
猜你喜欢
  • 1970-01-01
  • 2019-12-02
  • 2011-09-30
  • 2020-08-29
  • 2015-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多