【发布时间】:2010-08-04 11:00:17
【问题描述】:
我有一个进程启动事务,将记录插入 Table1,然后调用长时间运行的 Web 服务(最多 30 秒)。如果 Web 服务调用失败,则插入回滚(这是我们想要的)。这是插入的示例(实际上是对多个表的多次插入,但我正在简化这个问题):
INSERT INTO Table1 (UserId, StatusTypeId) VALUES (@UserId, 1)
我有第二个进程从第一步查询 Table1,如下所示:
SELECT TOP 1 * FROM Table1 WHERE StatusTypeId=2
然后为用户更新该行。当进程 1 运行时,Table1 被锁定,因此进程 2 将在进程 1 完成之前完成,这是一个问题,因为在进程 1 完成其 Web 服务调用时引入了长时间的延迟。
进程 1 只会插入 1 的 StatusTypeId,它也是唯一插入 Table1 的操作。进程 2 只会查询 StatusTypeId = 2。我想告诉进程 2 忽略对 Table1 的任何插入,但锁定它选择的行。 Process 2 的默认隔离级别等待太多,但我担心 IsolationLevel.ReadUncommitted 允许读取太多脏数据。我不希望两个用户运行 Process 2 然后意外地获得同一行。
除了 ReadUncommitted 之外,还有其他 IsolationLevel 可以使用,它表示忽略插入的行,但确保选择锁定选定的行?
【问题讨论】:
-
这些锁不应该冲突。你有
StatusTypeId的索引吗?SELECT TOP 1 * FROM Table1 WHERE StatusTypeId=2的ORDER BY是什么 -
您能否澄清“我不希望两个用户运行 Process2 然后意外获得同一行”的意思?因为这种情况在任何隔离级别都是完全可行的。
-
StatusTypeId 上没有索引,但 StatusTypeId 上有一个外键到 StatusType 表。不确定 StatusTypeId 上的外键是否也在该列上创建索引。
标签: sql sql-server transactions isolation-level