我们有一个从进度表中选择记录的过程,然后针对该记录发布更新。
如果我们不进行选择,那么更新会全天运行。如果我们进行选择,那么更新就会超时。
选择查询非常简单,如下所示:
select fg."alphakey", n."first-name", n."last-name"
from pub.name n
inner join pub."family-guardian" fg
on (fg."name-id" = n."name-id")
where fg."alphakey" = 'somevalue'
我们已经确认,如果上述声明不存在,那么它是有效的。但是,如果存在上述语句,则UPDATE失败。更新违反了名称表。不幸的是,我没有该代码,因为它是通过第三方执行的。
两个问题:
- 这是正常的进步吗?
- 解决此问题的最佳方法是什么?
如果在这种情况下脏读不是问题,您可以尝试表提示 readuncommitted 或 nolock..
使用 4GL
我认为解决此锁定问题的最佳方法是使用 4GL(有时称为 ABL)。在 4GL 中,神奇的命令是NO-LOCK,您可以在每个 table where 子句之后使用它。遗憾的是,4GL 不支持方便连接的 SQL 快捷方式名称。也就是说,如果您的索引定义正确,则EACH ... OF语法会取代它。如果没有,只需删除 OF 并将您的条件放在 where 子句中。只需为较慢的执行做好准备。
我们通过 Progress OpenEdge ODBC 驱动程序执行查询。
被
Default Isolation Level
设置在驱动程序上Read Committed
。我们做出这个选择时没有意识到SELECT
s 导致了一些长时间运行的表锁,而我们所追求的只是确保我们没有得到任何脏读。所以,我们有两个潜在的解决方案。首先是修改我们所有的查询以
with (nolock)
按照迈克尔的建议使用。第二个是将 ODBC 驱动程序更改为Read Uncommitted
.由于驱动程序设置更容易管理,无论如何我们都将被迫进行脏读,而我们的应用程序唯一要做的就是
SELECT
脱离该数据库,那么我们的选择就很明确了。