Sp_getAppLock是否会导致SQL Server性能问题



我有一个无法同时执行的存储过程。多个过程称此存储过程称为,但是该过程顺序访问存储过程至关重要。

存储过程基本上扫描了一个符合各种条件的主要键,将记录标记为通过调用过程中使用的记录,然后将主键传递回呼叫过程。

可以存在从一个到十几个实例的任何地方,具体取决于存在多少工作。

我决定通过在存储过程中使用sp_GetAppLock来防止并发。我抓住一个独家交易锁,将@Resource设置为仅在此存储过程中使用的字符串。该锁定唯一阻止的是执行此存储过程。

存储过程中的调用如下:

     sp_getapplock @Resource='My Unique String Here' 
         ,@LockMode='Exclusive'  -- Type of lock
         ,@LockOwner='Transaction' -- Transaction or Session
         ,@LockTimeout = 5000

它可以游泳。如果我的过程中有十几个实例正在运行,则只有一个时间点执行存储过程,而其他11个则要等待,然后等待他们。

唯一的问题是我们的DBA。他是一个非常好的DBA,他不断监视数据库,以阻止并在超过一定阈值时收到警报。我对sp_getapplock的使用触发了很多警报。我的DBA声称自己自身的阻塞是一个性能问题。

他的主张准确吗?我的感觉是,这是"好"的阻塞,因为唯一被阻止的是执行存储过程,而我想要将被阻止。但是我的DBA说,强迫SQL Server强制执行此阻塞是对资源的重大消耗。

我可以告诉他"放下裂缝管",就像我们以前所说的那样?还是我应该重写我的应用程序以避免需要sp_getapplock

我阅读的文章在sp_getapplock上卖给我的文章在这里:sp_getapplock

不幸的是,我认为您的DBA有一个要点,阻止确实会消耗资源,并且这种阻止正在为服务器添加额外的负载。

让我解释如何:

  1. proc被调用,SQL Server从线程池分配工作线程,并开始执行。

  2. 呼叫2,3,4,...进来,SQL Server再次分配了这些呼叫的Worker线程,线程开始执行在"Waiting List"中以获取资源可用。

  3. 由于您的流程而持有的任何SQL服务器的数字非常有限的工作线程。

  4. 现在,由于开发人员决定这样做,SQL Server正在累积等待。

作为DBA,我们希望您来到SQL Server获得所需的东西,并尽快留下它。如果您有意呆在那里,坚持资源并将SQL Server承受压力,它将惹恼DBA。

我认为您需要重新考虑应用程序设计并提出替代解决方案。

也许是SQL Server中的"过程表",在过程启动时使用某些值更新,并且每个呼叫首先检查过程表,然后再发射该Proc的下一个呼叫。因此,等待内容发生在应用程序层中,并且只有在资源可用时才发生,然后转到DB。

" 存储过程基本上扫描了一个符合各种条件的主键,将记录标记为通过调用过程中使用的记录,然后将主键传递给后键到呼叫过程。">
这是在SP中进行的另一种方法:

BEGIN TRANSACTION
 SELECT x.PKCol
   FROM dbo.[myTable] x WITH (FASTFIRSTROW XLOCK ROWLOCK READPAST)
  WHERE x.col1 = @col1...
 IF @@ROWCOUNT > 0 BEGIN
    UPDATE dbo.[myTable]
       SET ...
     WHERE x.col1 = @col1
 END
COMMIT TRANSACTION

xlock 指定要拿走并保留独家锁,直到交易完成为止。如果用Rowlock,Paglock或Tablock指定,则独家锁适用于适当的粒度水平。

最新更新