回答

收藏

存储过程中的SQLServer锁定表

技术问答 技术问答 330 人阅读 | 0 人回复 | 2023-09-14

我有一张99需要的桌子%自动分配时间ID(其他1%似乎用身份列来排除)。因此,我有一个存储过程来获得下一行的下一个ID:
8 b! h0 I1 J3 \: n# r``3 R6 j. {' L. u4 j4 E4 b
select @nextid = lastid 1 from last_auto_idcheck next available id in the table...update last_auto_id set lastid = @nextid必须检查用户是否手动使用。ID找到下一个未使用的,找到下一个未使用的ID。  V9 S. e# i+ t
当我依次调用它并返回1、2、3时,它可以正常工作。我需要做的是在多个过程中同时调用这种方法来提供一些锁定。理想情况下,我只需要它围绕这个代码锁定last_auto_id为了使第二次调用必须等待第一次调用更新表才能运行select。) B. K+ ~1 T: m
在Postgres中间,我可以执行类似的 LOCK TABLE last_auto_id;操作 显式锁定表。你觉得怎么样?SQL2 W- E, D& x" z! m: u4 s, b, a
Server完成它吗?+ R. V( k  v) z3 C% p3 _3 h8 D$ K
提前致谢!8 [; w# @% h7 R2 l8 w
                                                                7 v2 P4 }& w1 L+ x
    解决方案:                                                               
$ F- R6 M4 m+ ~+ N& q& d4 G0 ~                                                                你们之间回答了我的问题。我想发表我自己的回复,整理我在文章中发表的工作解决方案。关键似乎是事务处理方法last_auto_id表上有锁定提示。将事务隔离设置为可序列化似乎会导致死锁问题。9 m4 {% H' @8 s/ S
这就是我得到的(编辑显示完整代码,所以我希望我能得到更多的答案…):% @+ L1 j! f1 m7 h: a8 l
DECLARE @Pointer AS INTBEGIN TRANSACTION-- Check what the next ID to use should beSELECT @NextId = LastId   1 FROM Last_Auto_Id WITH (TABLOCKX) WHERE Name = 'CustomerNo'-- Now check if this next ID already exists in the databaseIF EXISTS (SELECT CustomerNo FROM Customer           WHERE ISNUMERIC(CustomerNo) = 1 AND CustomerNo = @NextId)BEGIN  -- The next ID already exists - we need to find the next lowest free ID  CREATE TABLE #idtbl ( IdNo int )  -- Into temp table,grab all numeric IDs higher than the current next ID  INSERT INTO #idtbl  SELECT CAST(CustomerNo AS INT) FROM Customer  WHERE ISNUMERIC(CustomerNo) = 1 AND CustomerNo >= @NextId  ORDER BY CAST(CustomerNo AS INT)  -- Join the table with itself,based on the right hand side of the join  -- being equal to the ID on the left hand side   1.  We're looking for  -- the lowest record where the right hand side is NULL (i.e. the ID is  -- unused)  SELECT @Pointer = MIN( t1.IdNo )  1 FROM #idtbl t1  LEFT OUTER JOIN #idtbl t2 ON t1.IdNo   1 = t2.IdNo  WHERE t2.IdNo IS NULLENDUPDATE Last_Auto_Id SET LastId = @NextId WHERE Name = 'CustomerNo'COMMIT TRANSACTIONSELECT @NextId这将在事务开始时取出排他表锁,然后表锁将所有其他请求成功排队,直到请求更新表并提交事务。
$ X- W+ e1 d  W* R" D我写了一些C代码与六个会话的并发请求一起使用,运行良好。
. q0 \( Y" O1 V1 y' n然而,我确实担心锁定提示这个词-有人知道SQLServer它是被视为确定的指令还是仅作为提示(也就是说,它可能不会一直服从它吗?
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则