在SQL Server中,如何以类似于Oracle的“SELECT FOR UPDATE WAIT”的方式锁定单个行? [英] In SQL Server, how can I lock a single row in a way similar to Oracle's "SELECT FOR UPDATE WAIT"?

查看:1150
本文介绍了在SQL Server中,如何以类似于Oracle的“SELECT FOR UPDATE WAIT”的方式锁定单个行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序连接到Oracle数据库并对其执行操作。

I have a program that connects to an Oracle database and performs operations on it. I now want to adapt that program to also support an SQL Server database.

在Oracle版本中,我使用SELECT FOR UPDATE WAIT来锁定我需要的特定行。我使用它的情况下,更新是基于SELECT的结果,其他会话可以绝对不能同时修改它,所以他们必须手动锁定它。系统非常需要尝试同时访问相同数据的会话。

In the Oracle version, I use "SELECT FOR UPDATE WAIT" to lock specific rows I need. I use it in situations where the update is based on the result of the SELECT and other sessions can absolutely not modify it simultaneously, so they must manually lock it first. The system is highly subject to sessions trying to access the same data at the same time.

例如:

两个用户尝试获取行在具有最高优先级的数据库中,将其标记为忙,对其执行操作,并将其标记为可用以供稍后使用。
在Oracle中,逻辑将基本上是这样的:

For example:
Two users try to fetch the row in the database with the highest priority, mark it as busy, performs operations on it, and mark it as available again for later use. In Oracle, the logic would go basically like this:

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秒后,将返回一个错误,并且操作将被取消。

Note that the queries are built dynamically in my code. Also note that when the previously most favorable row is marked as unavailable, the second user will automatically go for the next one and so on. Furthermore, different users working on different categories will not have to wait for each other's locks to be released. Worst comes to worst, after 5 seconds, an error would be returned and the operation would be cancelled.

最后,问题是:如何实现相同的结果在SQL Server?我一直在寻找锁定提示,在理论上,似乎他们应该工作。但是,阻止其他锁的唯一锁是UPDLOCK和XLOCK,它们都只在表级别工作。

在行级别工作的锁定提示都是共享锁,不满足我的需要(两个用户可以同时锁定同一行,都标记为不可用,并对相应的项执行冗余操作)。

So finally, the question is: how do I achieve the same results in SQL Server? I have been looking at locking hints which, in theory, seem like they should work. However, the only locks that prevents other locks are "UPDLOCK" AND "XLOCK" which both only work at a table level.
Those locking hints that do work at a row level are all shared locks, which also do not satisfy my needs (both users could lock the same row at the same time, both mark it as unavailable and perform redundant operations on the corresponding item).

有些人似乎添加了一个时间修改列,以便会话可以验证他们是谁修改它,但这听起来像会有很多冗余和不必要的访问。

Some people seem to add a "time modified" column so sessions can verify that they are the ones who modified it, but this sounds like there would be a lot of redundant and unnecessary accesses.

推荐答案

在SQL Server中有锁定提示,但它们没有跨越他们的语句,如你提供的Oracle示例。在SQL Server中执行此操作的方法是在包含要执行的语句的事务上设置隔离级别。请参见此MSDN页面,但其一般结构如下:

In SQL Server there are locking hints but they do not span their statements like the Oracle example you provided. The way to do it in SQL Server is to set an isolation level on the transaction that contains the statements that you want to execute. See this MSDN page but the general structure would look something like:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

BEGIN TRANSACTION;

    select * from ...

    update ...

COMMIT TRANSACTION;

SERIALIZABLE是最高的隔离级别。请参阅其他选项的链接。从MSDN:

SERIALIZABLE is the highest isolation level. See the link for other options. From MSDN:


SERIALIZABLE指定以下内容:

SERIALIZABLE Specifies the following:

语句无法读取数据已被修改,但尚未
由其他交易承诺。

Statements cannot read data that has been modified but not yet committed by other transactions.

没有其他交易可以修改由
当前交易读取的数据,直到当前事务完成。

No other transactions can modify data that has been read by the current transaction until the current transaction completes.

其他事务不能插入新行的键值将
落在当前$ b $中的任何语句读取的键范围内b交易,直到当前交易完成。

Other transactions cannot insert new rows with key values that would fall in the range of keys read by any statements in the current transaction until the current transaction completes.

这篇关于在SQL Server中,如何以类似于Oracle的“SELECT FOR UPDATE WAIT”的方式锁定单个行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆