Reputation: 1908
I have a very quick question in regards to sp_getapplock. Is calling sp_getapplock with the same resource (lock id) from one stored procedure to another allowed?
For example:
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
Since the @Resource (lock id) are the same, will it fail?
Upvotes: 2
Views: 2541
Reputation: 1604
Yes, you can call it multiple times - however if you call it twice you MUST release it twice. If the second call is stronger than the first then the result will be a union of the two.
Source BOL - sp_getapplock (Transact-SQL)
If sp_getapplock is called multiple times for the same lock resource, but the lock mode that is specified in any of the requests is not the same as the existing mode, the effect on the resource is a union of the two lock modes. In most cases, this means the lock mode is promoted to the stronger of the lock modes, the existing mode, or the newly requested mode. This stronger lock mode is held until the lock is ultimately released even if lock release calls have occurred before that time. For example, in the following sequence of calls, the resource is held in Exclusive mode instead of in Shared mode.
Source BOL - sp_releaseapplock (Transact-SQL)
Remarks
When an application calls sp_getapplock multiple times for the same lock resource, sp_releaseapplock must be called the same number of times to release the lock
Upvotes: 1
Reputation: 32693
I would expect that the call to sp_getapplock
from within uspTest2
return 0, i.e. "The lock was successfully granted synchronously", because you are holding this lock already in this transaction.
I think you are still in the same transaction and it is OK to call sp_getapplock
several times within the same transaction.
You should try and check.
You may have other problems with nested transactions, if you use them as you've shown, though. For example, if for any reason ROLLBACK
is called from uspTest2
, it will rollback all nested transactions, everything to the point when BEGIN TRANSACTION
was called in uspTest1
. Do you really want it?
Instead of using nested BEGIN TRANSACTION
in uspTest2
consider using SAVE TRANSACTION savepoint_name
and then ROLLBACK savepoint_name
.
Upvotes: 3