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

存储过程中的SQLServer锁定表

于高雅
2023-03-14
问题内容

我有一张桌子,我需要在99%的时间内自动分配ID(其他1%似乎使用身份列来排除)。因此,我有一个存储过程来获取以下行中的下一个ID:

``

select @nextid = lastid+1 from last_auto_id
check next available id in the table...
update last_auto_id set lastid = @nextid

检查必须检查用户是否手动使用了ID并找到下一个未使用的ID。

当我依次调用它并返回1、2、3时,它可以正常工作。我需要做的是在多个进程同时调用此方法的情况下提供一些锁定。理想情况下,我只需要它专用于围绕此代码锁定last_auto_id表,以便第二个调用必须等待第一个调用更新表才能运行它的select。

在Postgres中,我可以执行类似“ LOCK TABLE last_auto_id;”的操作 显式锁定表。有什么想法如何在SQL
Server中完成它吗?

提前致谢!


问题答案:

你们之间回答了我的问题。我要发表自己的答复,以整理我发表在一篇文章中的工作解决方案。关键似乎是事务处理方法,在last_auto_id表上具有锁定提示。将事务隔离设置为可序列化似乎会产生死锁问题。

这就是我所得到的(已编辑以显示完整的代码,因此希望我可以得到更多的答案…):

DECLARE @Pointer AS INT

BEGIN TRANSACTION

-- Check what the next ID to use should be
SELECT @NextId = LastId + 1 FROM Last_Auto_Id WITH (TABLOCKX) WHERE Name = 'CustomerNo'

-- Now check if this next ID already exists in the database
IF 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 NULL
END

UPDATE Last_Auto_Id SET LastId = @NextId WHERE Name = 'CustomerNo'

COMMIT TRANSACTION

SELECT @NextId

这将在事务开始时取出排他表锁,然后该表锁成功地将所有其他请求排队,直到此请求更新了表并提交了它的事务之后。

我编写了一些C代码,以将其与来自六个会话的并发请求一起使用,并且运行良好。

但是,我确实有个担心,那就是锁定“提示”一词-有人知道SQLServer是将其视为确定的指令还是仅作为提示(即,它可能不会始终服从它吗?)。



 类似资料:
  • 本文向大家介绍查询Sqlserver数据库死锁的一个存储过程分享,包括了查询Sqlserver数据库死锁的一个存储过程分享的使用技巧和注意事项,需要的朋友参考一下 使用sqlserver作为数据库的应用系统,都避免不了有时候会产生死锁, 死锁出现以后,维护人员或者开发人员大多只会通过sp_who来查找死锁的进程,然后用sp_kill杀掉。利用sp_who_lock这个存储过程,可以很方便的知道哪个

  • 本文向大家介绍sqlserver中存储过程的递归调用示例,包括了sqlserver中存储过程的递归调用示例的使用技巧和注意事项,需要的朋友参考一下 递归式指代码片段调用自身的情况;危险之处在于:如果调用了自身一次,那么如何防止他反复地调用自身。也就是说提供递归检验来保证适当的时候可以跳出。 以阶层为例子说存储过程中递归的调用。 递归 当创建此存储过程时候,会遇见一条报告信息

  • 本文向大家介绍谈谈sqlserver自定义函数与存储过程的区别,包括了谈谈sqlserver自定义函数与存储过程的区别的使用技巧和注意事项,需要的朋友参考一下 一、自定义函数:   1. 可以返回表变量   2. 限制颇多,包括     不能使用output参数;     不能用临时表;     函数内部的操作不能影响到外部环境;     不能通过select返回结果集;     不能update

  • 问题内容: 我在任何地方都找不到此答案,但是可以从MySQL中的另一个存储过程调用存储过程吗?我想找回标识值,并在父存储过程中使用它。我们不能再使用FUNCTIONS! 问题答案: 参数应该可以帮助您将值返回给调用过程。基于此,解决方案必须是这样的。

  • 问题内容: 我试图在postgres 9.3上使用sql调用函数内的函数。 这个问题与我的另一篇文章有关。 我写了下面的函数。到目前为止,我还没有合并任何类型的save-output(COPY)语句,因此我试图通过创建嵌套函数print-out函数来解决此问题。 以上功能有效。 尝试创建嵌套函数。 调用嵌套函数。 输出 上面给出了这个。但是,当在print_out()中将arg1,arg2替换为’

  • 正在获取以下异常 Java语言lang.RuntimeException:启动组织时出错。neo4j。内核位于组织的EmbeddedGraphDatabase。neo4j。内核InternalAbstractGraphDatabase。在org上运行(InternalAbstractGraphDatabase.java:335)。neo4j。内核EmbeddedGraphDatabase。(Emb