如何限制单个用户访问存储过程?

由于有些存储过程涉及到很多表数据的更改,所以每次只能运行一个用户访问。如果多个用户访问的话就会造成数据的出现问题(比如存储过程使用一张中间表做数据存储,会用到删除更新,如果第一个用户正在更新的时候,第二个用户删除数据,那么第一个用户的数据就会丢失)。曾经看到有用控制板来控制存储过程的运行。运行存储过程之前先检查控制表的状态,如果发现有用户正在运行则返回错误结果。

 

其实不需要额外开发只需要调用系统存储过程sp_getapplock就可以实现相同的功能。使用sp_getapplock可以对应用程序资源设置锁。

 

--首先创建测试表并且插入数据:

CREATE TABLEperson(namevarchar(20),idint)

insert into person values ('kevin',1)

 

--创建自定义错误信息

EXECUTE sp_addmessage

  @msgnum  = 51005,

   @severity = 16,

   @msgtext  = N'Someone is running thisstored proc, please try later.',

   @lang     = 'us_english',

   @replace  = REPLACE

 

 

--创建存储过程在存储过程中使用sp_getapplock  

CREATE PROCEDUREusp_Test

  ( @ID   int,

      @Name     varchar(20)

   )

AS

   BEGIN

      SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

      BEGIN TRANSACTION

      DECLARE @LockResult int

      EXECUTE @LockResult = sp_getapplock

         @Resource   = 'testsp_getapplock',

         @LockMode    = 'Exclusive',

         @LockTimeout = 0

         IF @LockResult <> 0

           BEGIN

              ROLLBACK TRANSACTION

              RAISERROR (51005, 16, 1)

              RETURN

           END

         -- 获得独占所以后可以确保下面的语句只能有一个用户执行

          --   为了测试这里等待30S

         WAITFOR DELAY '00:00:20'

         UPDATE person    SET name= @Name      WHEREid = @ID

         EXECUTE sp_releaseapplock

            @Resource= 'testsp_getapplock'

      COMMIT TRANSACTION

   END

GO

 

 

打开一个查询界面执行下面的语句:

usp_Test 1,'allen'

  

在另外一个查询界面执行同样的语句会得到错误:

Msg 51005, Level 16, State 1,Procedure usp_Test, Line 21

Someone is running this stored proc,please try later.

 

等到第一个查询界面的语句执行成功后在执行第二个查询语句成功

 

另外sp_getapplock还可以用来解决多个用户同时获取最大值的问题。需要注意的是程序在调用存储过程的时候需要根据错误作出相应的处理,比如重拾等等。 

 

更多信息参考MSDN: http://msdn.microsoft.com/zh-cn/library/ms189823.aspx


本文转自 lzf328 51CTO博客,原文链接:

http://blog.51cto.com/lzf328/1030132
上一篇:OFFICE2007 WORD中无法使用鼠标拖动和选取菜单项


下一篇:使用SAP Analytics Cloud显示新冠肺炎病毒感染人数的实时信息