sql - 事务内的 sp_getapplock 事务

标签 sql sql-server stored-procedures

我有一个关于 sp_getapplock 的非常简单的问题。 是否允许从一个存储过程到另一个存储过程使用相同资源(锁定 ID)调用 sp_getapplock?

例如:

CREATE PROCEDURE [uspTest1]
(
    ...
    ...
)
AS
BEGIN TRY
    BEGIN TRANSACTION
        ...
        ...
        EXEC @RC = sp_getapplock @Resource = "Test 123",
                                 @LockMode = 'Exclusive',
                                 @LockOwner = 'Transaction',
                                 @LockTimeout = 60000,
                                 @DbPrincipal = 'public';
        IF @RC NOT IN (0, 1) THROW 50000, 'Unable to obtain lock', 1;
        ...
        ...
        EXEC [uspTest2] ..., ..., ...
    COMMIT
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION;
    THROW
END CATCH


-- Test 2
CREATE PROCEDURE [uspTest2]
(
    ...
    ...
)
AS
BEGIN TRY
    BEGIN TRANSACTION
        EXEC @RC = sp_getapplock @Resource = "Test 123",
                                 @LockMode = 'Exclusive',
                                 @LockOwner = 'Transaction',
                                 @LockTimeout = 60000,
                                 @DbPrincipal = 'public';
        IF @RC NOT IN (0, 1) THROW 50000, 'Unable to obtain lock', 1;
        ...
        ...
        ...
    COMMIT
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION;
    THROW
END CATCH

既然@Resource(锁id)相同,会失败吗?

最佳答案

我希望调用 sp_getapplockuspTest2 中返回 0,即“已成功同步授予锁”,因为您已在此事务中持有此锁。

我认为您仍然处于同一事务中,并且可以在同一事务中多次调用 sp_getapplock

您应该尝试检查。

不过,如果您按照所示方式使用嵌套事务,则可能会遇到其他问题。例如,如果出于任何原因从 uspTest2 调用 ROLLBACK,它将回滚所有嵌套事务,直到调用 BEGIN TRANSACTION 时为止的所有事务在uspTest1中。你真的想要吗?

不要在 uspTest2 中使用嵌套的 BEGIN TRANSACTION,而是考虑使用 SAVE TRANSACTION savepoint_name然后ROLLBACK savepoint_name

关于sql - 事务内的 sp_getapplock 事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32674364/

相关文章:

sql-server - 区分大小写的字符串比较

sql - 在新页面的页脚字段中显示溢出

mysql - 每行具有可变列数的 SELECT 查询

SQL 分组和某个日期范围内未清项目的运行总计

sql-server - 空间数据类型(几何)到 GeoJSON

sql-server - VARCHAR 长度有什么理由为 (2^n) - 1?

sql - SQL中如何复制表避免游标?

sql - 如何合并两个sql查询?

sql - PostgreSQL 无法聚合来自多个表的数据

c# - 更新数千条记录的最有效方法是什么