【问题标题】:What is the correct isolation level for Order header - Order lines transactions?订单标题的正确隔离级别是什么 - 订单行交易?
【发布时间】:2017-07-03 20:11:42
【问题描述】:

假设我们有 Order_Header 和 Order_LineItems 表的常见情况。 另外,假设我们有用于创建、更新和选择订单的交易。喜欢:

创建:

BEGIN TRANSACTION

INSERT INTO Order_Headers...

SET @Id = SCOPE_IDENTITY()

INSERT INTO Order_LineItems...(using @Id)

DECLARE @SomeVar INT

--just example to show update dependant on select
SELECT @SomeVar = COUNT(*) Order_Headers
WHERE OrderDate > '1-1-2017'

UPDATE Order_Headers
SET SomeValue = @SomeVar
WHERE Id = @Id

COMMIT

END TRANSACTION

另一方面,我们有基于某些标准获取订单的交易,为简单起见,假设是最后 10 个:

SELECT TOP 10 * FROM Order_Headers
ORDER BY Id DESC

有人能说出每个事务的正确隔离级别是什么,并简要解释一下原因吗?

[更新]

  1. 我想确保没有其他会话可以插入匹配的行 WHERE OrderDate > '1-1-2017'

  2. 我还想确保第二笔交易(纯选择订单)永远不会选择在第一笔交易中未完全“完成”的行。意思是那些在事务 INSERT 部分中创建但尚未在 UPDATE 部分中更新的那些。 (我猜这是默认的 READ COMMITED 所涵盖的,对吧?)

[更新 2]

我想要

WHERE OrderDate > '1-1-2017'

成为交易开始时的价值。

【问题讨论】:

  • 你要防范什么?您是否要确保在您提交之前没有其他数据库会话可以为@Ids 插入 Order_LineItems?是否要阻止其他人在您提交之前插入匹配 WHERE OrderDate > '1-1-2017' 的行?
  • 添加到@BenGribaudo,问题,您希望WHERE OrderDate > '1-1-2017' 的结果在事务开始时或SELECT 查询运行时成为值?
  • 大家好,感谢两位提出的好问题!我已经更新了我的问题。
  • @deezg,如果您可以确保读取的值在事务开始时,我不确定您为什么要阻止并发会话插入。所需的隔离级别可以通过行版本控制而不是锁定来实现(即 SNAPSHOT 而不是 SERIALIZABLE)。
  • @Dan 好吧,这是个好问题。没有认为它是相关的。实际上,我想要最简单的方法来确保我不会因订单的错误结果而发生冲突。你是对的,如果从事务开始就确保值是 1,那么阻止并发更新就没有意义了。你会如何处理这种情况?您最喜欢的解决方案是什么?

标签: sql sql-server transaction-isolation


【解决方案1】:

首先确保您的数据库已启用快照隔离

ALTER DATABASE YOURDB
SET ALLOW_SNAPSHOT_ISOLATION ON

第一个事务需要 SNAPSHOT 隔离

SET TRANSACTION ISOLATION LEVEL SNAPSHOT

第二个事务需要 READ COMMITTED 隔离

 SET TRANSACTION ISOLATION LEVEL READ COMMITTED

【讨论】:

    猜你喜欢
    • 2012-05-09
    • 2018-05-26
    • 2020-08-29
    • 2011-08-24
    • 2018-11-21
    • 2016-08-08
    • 2019-07-18
    • 2020-03-06
    • 2018-01-26
    相关资源
    最近更新 更多