当前位置: 首页 > 面试题库 >

SQL Server:如何获取排他锁以防止出现竞争状况?

江敏学
2023-03-14
问题内容

我有以下T-SQL代码:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION T1_Test

    /*This is a dummy table used for "locking" 
    and it doesn't contain any meaningful data.*/        
    UPDATE lockTable 
        SET ID = 1    
        WHERE ID = 1

    DECLARE @Count TINYINT

    SELECT @Count = COUNT(*)
    FROM debugSP

    WAITFOR DELAY '00:00:5';

    INSERT INTO debugSP 
        (DateCreated, ClientId, Result)
    SELECT 
        GETDATE(), @@SPID, @Count

COMMIT TRANSACTION T1_Test

我正在使用带有注释的“锁定”黑客来获取排他锁定。

注意:使用TABLOCKX或UPDLOCK提示将不起作用,因为我通过拆分语句并在中间添加WAITFOR命令进行测试而破坏了ATOMIC-
ity。我不要这样的东西:

INSERT INTO debugSP (DateCreated, ClientId, Result)
SELECT GETDATE(), @@SPID, COUNT(*) 
FROM debugSP

在同时运行两个会话(带锁表)之后,这是正确的结果

Id DateCreated           ClientId Result
-- ----------------------- -------- ------
 1 2011-03-17 15:52:12.287       66      0
 2 2011-03-17 15:52:24.534       68      1

那是运行带有注释的代码的不正确结果

Id DateCreated           ClientId Result
-- ----------------------- -------- ------
 1 2011-03-17 15:52:43.128       66      0
 2 2011-03-17 15:52:46.341       68      0

没有这样的黑客,有没有更好的方法来获取交易范围内的排他锁?


问题答案:

我不确定从发布的代码中您要做什么。我想您只是在尝试序列化对那段代码的访问?如果是这样,sp_getapplock则应执行所需的操作,而不是创建仅用于锁定的新虚拟表。

详情在这里



 类似资料:
  • 问题内容: 我正在使用具有connect-redis的nodejs来存储会话数据。 我将用户数据保存在会话中,并在会话生存期内使用它。 我注意到,在两个更改会话数据的请求之间可能存在竞争状态。 我尝试使用redis-lock锁定会话,但是对我来说有点麻烦。 我不想锁定整个会话,而是只锁定特定的会话变量。 我发现这是不可能的,我考虑了解决的方向: 停止使用会话对象存储用户数据,并将变量直接保存在re

  • 在使用ACK时,有没有一种简单的方法实现类似于“锁定”的东西来防止RabbitMQ队列中的竞争条件? 我有以下问题--我有几个客户机使用ACK使用队列。每当客户端收到消息时,他就会确认并处理消息。但是,如果由于某种原因处理失败,我希望消息返回到队列。

  • 问题内容: 嗨,专家,我如何在SQL Server中锁定行,以防止CRUD操作(甚至是SELECT)。是否有可能?可序列化的隔离级别不会阻止SELECT。谢谢 问题答案: 这样就可以了。 编辑 正如其他人所指出的,您不能将行锁定为不被读取 。我知道这样做的唯一方法如下: 并假设在SELECT语句中从未使用过WITH(NOLOCK)(无论如何应避免使用)。 我测试了这一点,并且可以正常工作,尽管TA

  • 我正在做分类帐模块。在这个过程中,我必须按顺序完成这些任务 从源中选择余额(table 1 row1) 从目标中选择余额(table 1 row2) 用一些逻辑修改余额 更新源的余额(table 1 row1) 更新目标余额(table 1 row2) 提交更改 将事务插入到事件表中。 在多线程环境中,线程在前一个线程更新和提交之前获得余额。在Postgres中,锁被强加给正在被访问的行,直到线程

  • 问题内容: 我有以下代码(为清楚起见已简化): (上面的一些代码是从此答案中借用的。) 一次运行多个进程时,此代码仅导致一个进程打开并写入(假定尚不存在)。问题在于,当该进程正在写入时,其他进程会尝试加载-在后者的进程中会引发错误,因为在读取时,它是不完整的。(特别是,引发s,因为进程正在尝试导入文件的内容。) 避免这些错误的最佳方法是什么?一种想法是让进程继续尝试在while循环中进行导入,直到

  • 问题内容: 如何获得对文件的专有读取访问权?我已经尝试过docs中的文档,但是我仍然能够在记事本中打开文件并进行编辑。我想拒绝任何其他进程具有读写权限,而第一个进程没有明确关闭它。在.NET中,我可以执行以下操作: 我该怎么办? 问题答案: 我终于找到了可以锁定文件的go包。 这是仓库: https : //github.com/juju/fslock 这个包裹完全按照它说的去做 fslock提供