【发布时间】:2017-02-15 15:11:21
【问题描述】:
我有一个场景,我在一段时间内运行多个 SQL 查询。在整个场景中,Update 语句可能会与 Select 语句同时运行,从而影响同一个表。发生这种情况时,我的 SqlDataReader 对象运行 Select 查询并且不返回任何行。但是,立即重试 Select 查询将导致接收到正确的数据。 Select 语句实际上应该永远不会返回任何数据。
虽然我可以在读取失败后重试查询以获得结果,但我想首先避免这种冲突,或者至少有一种方法可以区分实际读取没有行和发生这种冲突错误。在检查 SqlDataReader 对象时,告诉我读取失败的唯一不同属性是 HasRows 设置为 false,这对于我在这里寻找的内容来说不够具体。此外,尝试读取只会返回 false,并且不会引发可能说明读取失败原因的错误。
到目前为止,我已经尝试在 Select 和 Update 查询上都加锁,但我没有这样的运气。理想情况下,Update 语句将有一个锁,该锁将排队,而不是阻塞,Select 查询从运行直到事务完成之后。我尝试了几种不同的锁变体,但我尝试的一个例子是:
update <Tablename> with (TABLOCKX, HOLDLOCK) set ...
这并没有像我预期的那样停止碰撞,所以这就是我被卡住的地方。
如果我知道永远不应该有空读取,这里最好的方法是重试吗,或者是否有更好的方法,就像我建议的那样使用 SQL 锁?
【问题讨论】:
-
如果您正在更新一行,您的选择语句应该等待锁被释放。除非您在更新中使用查询提示并且您已经阅读过这会改变这种行为。
-
目前,我拥有的唯一锁定语句是更新语句中的。
标签: c# sql-server locking collision sqldatareader