【发布时间】:2012-03-19 03:00:00
【问题描述】:
我有一个连接到 Oracle 数据库并对其执行操作的程序。我现在想调整该程序以支持 SQL Server 数据库。
在 Oracle 版本中,我使用“SELECT FOR UPDATE WAIT”来锁定我需要的特定行。我在更新基于 SELECT 的结果并且其他会话绝对不能同时修改它的情况下使用它,因此他们必须先手动锁定它。系统很容易受到试图同时访问相同数据的会话的影响。
例如:
两个用户尝试获取数据库中具有最高优先级的行,将其标记为忙碌,对其执行操作,并将其再次标记为可用以供以后使用。
在 Oracle 中,逻辑基本上是这样的:
BEGIN TRANSACTION;
SELECT ITEM_ID FROM TABLE_ITEM WHERE ITEM_PRIORITY > 10 AND ITEM_CATEGORY = 'CT1'
ITEM_STATUS = 'available' AND ROWNUM = 1 FOR UPDATE WAIT 5;
UPDATE [locked item_id] SET ITEM_STATUS = 'unavailable';
COMMIT TRANSACTION;
请注意,查询是在我的代码中动态构建的。另请注意,当先前最有利的行被标记为不可用时,第二个用户将自动转到下一个,依此类推。此外,处理不同类别的不同用户不必等待彼此的锁被释放。最坏最坏,5秒后返回错误并取消操作。
最后,问题是:如何在 SQL Server 中获得相同的结果?我一直在研究锁定提示,从理论上讲,它们似乎应该起作用。但是,阻止其他锁的唯一锁是“UPDLOCK”和“XLOCK”,它们都只能在表级别工作。
那些在行级别起作用的锁定提示都是共享锁,这也不能满足我的需求(两个用户可以同时锁定同一行,都将其标记为不可用并对相应的项执行冗余操作)。
有些人似乎添加了“时间修改”列,以便会话可以验证他们是修改它的人,但这听起来会有很多冗余和不必要的访问。
【问题讨论】:
标签: sql-server database oracle concurrency locking