i have following code:
set transaction isolation level read committed; --this clarity declare @jobname nvarchar(128); begin tran select @jobname = jobname dbo.jobdetails executionstate_status = 1 waitfor delay '00:00:10' update dbo.jobdetails set executionstate_status = 10 jobname = @jobname commit
and second piece that's same:
set transaction isolation level read committed; declare @jobname nvarchar(128); begin tran select @jobname = jobname dbo.jobdetails executionstate_status = 1 waitfor delay '00:00:15' update dbo.jobdetails set executionstate_status = 20 jobname = @jobname commit
the difference in status we're setting (10 vs 20) , delay (10s vs 15s).
i'm executing them in parallel in management studio - 2 tabs. problem - read committed transaction isolation level works expected - last modification applied , both scripts execute .
however that's not want - want execute 1 , second should nothing. that's why tried change level repeatable read. according knowledge (which want challenge right now) should behave this:
- first transaction starts , locks rows reads
- first transaction waiting 10 seconds
- second transaction starts in meantime , cannot execute select since it's locked first one
- first transaction finishes wait, updates table & commits
- second transaction can proceed , nothing since rows status = 1 updated
unfortunately results i'm seeing far - transactions deadlocked , 1 of them killed sql server. don't understand why happening since accessing resources in same order.
here scripts necessary testing:
create table [dbo].[jobdetails]( [jobname] [nvarchar](128) not null, [executionstate_status] [int] null default ((0)), constraint [pk_dbo.jobdetails] primary key clustered ( [jobname] asc )) go insert jobdetails values( 'my job', 1) update jobdetails set executionstate_status = 1
additional notes:
- i'm testing 1 row in table.
- changing level serializable results in deadlock.
- the reason why code looks because i'm trying simulate orm going - first entity, check in code if status 1 , send update
where
based on pk. know write code without orm having updatewhere executionstate_status = 1
this assumption wrong:
second transaction starts in meantime , cannot execute select since it's locked first one
both repeatable read
transactions' select
s aquire , hold s
locks on key till commit
. s
locks compatible. deadlocked when update
trying x
lock incompatible s
lock. contrary that, select
in read commited
transaction immediatley releases s
lock.
use exec sp_lock , see locks, e.g.
declare @jobname nvarchar(128); begin tran select @jobname = jobname dbo.jobdetails executionstate_status = 1 waitfor delay '00:00:10' exec sp_lock 58,57 update dbo.jobdetails set executionstate_status = 10 jobname = @jobname commit
Comments
Post a Comment