问题
I've an existing stored procedure SP1 which is simple select from a table. It's being used at multiple places.
Now there is a new code which uses this SP1 along with an update statement in one serializable transaction. I'm seeing deadlock where two transactions are able to acquire read lock on same set of rows and now want to convert that lock to update.
One possible solution is to make this SP1 execute in read committed isolation level. But I think this is not the right fix, as there can be lost updates. Another solution is to hint UPDLOCK
in SP1's select statement. This will resolve the deadlock as whatever transaction acquires that UPDLOCK will only proceed. The other transaction will have to wait for this to commit.
Now adding UPDLOCK
to this SP1 unnecessarly adds this overhead for other places which call SP1 but don't want UPDLOCK
. So one might think to duplicate this SP1 and have new SP1UPDLOCK
which is same as SP1 but with UPDLOCK
. I don't want this duplication.
So is there any way caller can hint that whatever SP1 returns should be take with UPDLOCK.
Any other better way to solve this type of issue.
I'm using SQL server 2008, C#, .NET 4.
Sample Code
CREATE PROCEDURE SP1
@SomeId int
AS
BEGIN
Select Foo From Bar Where SomeOne = @SomeId
END
CREATE PROCEDURE SP1UPDLOCK
@SomeId int
AS
BEGIN
Select Foo From Bar (UPDLOCK) Where SomeOne = @SomeId
END
CREATE PROCEDURE SP2
@Foo int
@SomeId int
AS
BEGIN
Update Bar
Set Foo = @foo
Where SomeOne = @someId
End
C# code
Using(Transaction t = new Transaction())
{
result = SP1(someId);
// some logic here
if(somecond == true)
{
SP2(fooVal, someId);
}
t.Commit();
}
回答1:
If the calls to SP1 follows by SP2 are atomic, they should be combined in T-SQL. Or lose the c# transaction. You are prolonging the transaction unnecessarily with roundtrips.
Also, why have UPDLOCK on SP1UPDLOCK but not for SP1? I can't see why. If the problem is lock hints, don't use them. If something is serializable (why?) then again, make it a single atomic call
Note that the default is READ COMMITTED anyway
Finally, do you mean "semaphore" not lock? Using sp_getapplock will control flow through the code without using locks on the data
来源:https://stackoverflow.com/questions/6983216/how-to-hint-update-lock-without-duplicating-stored-procedure-code