sql - 防止同时执行存储过程
问题描述
我有一个存储过程,它将记录插入到具有顺序令牌编号的表中。我有另一个存储过程,它也将记录插入到同一个表中。
我将从 Web 应用程序的不同用户执行这些存储过程。
例如,我的 Web 应用程序中有一个名为 AddUser 的页面,OfficerA 和 OfficeB 可以访问该页面。这两位官员可以同时按下将同时执行我的存储过程的添加按钮。如果这样做,2 个新用户将获得相同的令牌编号,这不应该发生。
我想创建一个锁定机制,如果一名官员执行该程序,其他官员执行应该等待到第一个完成。
我尝试了以下方法。但不确定它对于等待过程是否足够
create procedure TokenInsertProc(<params here>)
as
begin
DECLARE @returnCode INT
BEGIN TRANSACTION;
BEGIN TRY
EXEC @returnCode = sp_getapplock
@Resource = 'TokenInsertProc',
@LockMode = 'Exclusive',
@LockOwner = 'Transaction',
@LockTimeout = 50,
@DbPrincipal = 'public'
IF @returnCode NOT IN (0, 1)
BEGIN
RAISERROR ( 'Unable to acquire exclusive Lock on TokenInsertProc', 16, 1 )
RETURN
END
-- my procedure insert script goes here
EXEC @returnCode = sp_releaseapplock
@Resource = 'TokenInsertProc',
@LockOwner = 'Transaction',
@DbPrincipal = 'public'
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @returnCode IN (0, 1)
BEGIN
EXEC @returnCode = sp_releaseapplock
@Resource = 'TokenInsertProc',
@LockOwner = 'Transaction',
@DbPrincipal = 'public'
END
DECLARE @ErrMsg VARCHAR(4000)
SELECT @ErrMsg = ERROR_MESSAGE()
RAISERROR(@ErrMsg, 15, 50)
ROLLBACK TRANSACTION;
END CATCH;
end
或者只是
set transaction isolation level serializable
会有所帮助?
create procedure TokenInsertProc(<params here>)
as
begin
DECLARE @returnCode INT
set transaction isolation level serializable
BEGIN TRANSACTION;
BEGIN TRY
-- my procedure insert script goes here
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH;
end
任何帮助都感激不尽。
编辑 1
为了更清楚,让我发布表格结构
TQHId TokenNo TokenStatus TokenSequence
1 A1 Pending 1
6 A2 Pending 2
7 B1 Pending 1
9 I3 Hold 3
10 I4 Pending 4
在这张表中
[TQHId] [int] IDENTITY(1,1) NOT NULL, CONSTRAINT [PK_TokenQHeader] PRIMARY KEY CLUSTERED
(
[TokenQHeaderId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
是与 tokenno 没有任何关系的身份字段。我用它作为主键字段。我的令牌编号是使用TokenInsertProc过程中的自定义代码生成的。
正如我提到的,我的问题是这个存储过程可能会同时被两个不同的网络用户调用。我想避免将相同的令牌编号(仅在执行过程时)提供给 2 个不同的用户。
解决方案
推荐阅读
- node.js - 节点 express REST API 中的 CORS 错误(PATCH 请求)
- python - 如何将绝对路径转换为函数内的相对路径?
- ios - SwiftUI - 显式动画的快速序列产生奇怪的动画
- android - 从过滤列表视图输入数据时,如何在存储的项目中获取数据?
- reactjs - NextAuth.js 用于与 Google 进行身份验证的 [client_fetch_error] 与 next.js
- java - 如何使用 Envers 跟踪更改等子更新父的当前版本与更改的子的当前版本相关联?
- android - Android View XML 中的数据绑定条件语句过多,如何在没有额外监听器的情况下移动到 ViewModel
- html - 尝试使用显示使主页上的文本居中:使用标题时的弹性
- php - 为什么 get_posts 函数会显示除一篇之外的所有文章?
- python - Seaborn:在 Y 轴上绘制一个显示属性均值的条形图?