"Ulrich" <crowh...@gmx.net> wrote in message <news:evJRVP0YCHA.1152@tkmsftngp10>...
> see sp_getapplock in BOL
> "Andrew John" <a...@NOSPAMmistrose.com> wrote in message
> news:#idT66oYCHA.2264@tkmsftngp09...
> > Tim,
> > Yes, in hindsite I should have kept quiet and seen if anyone else was
> going to respond, as I am aware of this
> > limitation - It takes 2 updates, one to grab the row, then the 2nd after
> all the processing results are ready.
> > What you are really after is something like a SELECT statement, using a
> combination of READPAST and HOLDLOCK,
> > but these do not work together in a select. - I have tried extensively,
> and have both today, and
> > previously searched in vain for working code posted in this newsgroup, or
> the internet at large.
> > This is the best I can come up with:
> > declare @location int
> > set @location = NULL
> > update Locations with (HOLDLOCK)
> > set @Location = Location,
> > unused = 1
> > where Location =
> > (
> > select top 1 Location
> > from Locations with ( READPAST )
> > where unused = 0
> > order by Location
> > )
> > IF @location is not NULL
> > BEGIN
> > -- Do other stuff
> > waitfor delay '000:00:10'
> > update Locations
> > set SomeOtherCol = SomeOtherCol + 'Tran1'
> > where location = @location
> > if @@rowcount <> 1
> > BEGIN
> > -- Error handling
> > print 'No Update'
> > END
> > END
> > ELSE
> > BEGIN
> > -- Error Handling
> > print 'No free row'
> > END
> > The holdlock is probably not required in this example.
> > Puting it all in a transaction so you can cancel the 1st update if the
> processing or 2nd fails is a reasonable
> > extension. If this approach is not suitable, then I suggest you repost
> with something like
> > "How do I select with HOLDLOCK and READPAST, in order to implement a work
> queue"
> > and I'll keep my mouth shut this time.
> > Regards
> > AJ
> > "Tim B" <t...@innov8uk.com> wrote in message
> news:#1I3UoLYCHA.2032@tkmsftngp11...
> > > Hi Andrew,
> > > many thanks for the quick reply. Please try the same
> test as
> > > you used below however with the waitfor "BETWEEN the SELECT and the
> UPDATE".
> > > Your sample has probably executed the first update before the second
> > > transaction starts running, This update is then locking the record,
> which
> > > then causes the second transaction to readpast the locked record and
> suggest
> > > the next available record. However as the work is being done between
> the
> > > select and the update, if the select doesnt lock the record from being
> seen
> > > from a different transaction both transactions could have the same
> Location
> > > before they perform the update.
> > > Thanks greatly in advance
> > > Tim
> > > "Andrew John" <a...@NOSPAMmistrose.com> wrote in message
> > > news:#zVO9MLYCHA.2292@tkmsftngp12...
> > > > Tim,
> > > > Works fine for me. Here is the test code I used
> > > > ( normal newsgroup practise is for YOU to supply this, in order to
> provide
> > > > us with less typing ! )
> > > > Data:
> > > > create table Locations
> > > > (
> > > > Location int identity ( 1, 1 ),
> > > > unused int,
> > > > SomeOtherCol varchar ( 30)
> > > > )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'First' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Second' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Third' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Fourth' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Fifth' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Sixth' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Seventh' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Eighth' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Nineth' )
> > > > insert into Locations ( unused, SomeOtherCol ) values ( 0, 'Tenth' )
> > > > Query 1:
> > > > declare @location int
> > > > set @location = NULL
> > > > select top 1 @location = Location
> > > > from Locations with (READPAST)
> > > > where unused = 0
> > > > order by Location
> > > > IF @location is not NULL
> > > > BEGIN
> > > > update Locations with (holdlock) set unused = 1 where location =
> @location
> > > > IF @@Rowcount = 1
> > > > BEGIN
> > > > -- Do other stuff
> > > > waitfor delay '000:00:20'
> > > > update Locations set SomeOtherCol = SomeOtherCol + 'Tran1' where
> location = @location
> > > > END
> > > > ELSE
> > > > BEGIN
> > > > -- Error handling
> > > > print 'No Update'
> > > > END
> > > > END
> > > > ELSE
> > > > BEGIN
> > > > -- Error Handling
> > > > print 'No free row'
> > > > END
> > > > Query 2: ( started a couple of seconds after Query 1 - only
> difference is
> Tran2 vs Tran1 )
> > > > declare @location int
> > > > set @location = NULL
> > > > select top 1 @location = Location
> > > > from Locations with (READPAST)
> > > > where unused = 0
> > > > order by Location
> > > > IF @location is not NULL
> > > > BEGIN
> > > > update Locations with (holdlock) set unused = 1 where location =
> @location
> > > > IF @@Rowcount = 1
> > > > BEGIN
> > > > -- Do other stuff
> > > > waitfor delay '000:00:20'
> > > > update Locations set SomeOtherCol = SomeOtherCol + 'Tran2' where
> location = @location
> > > > END
> > > > ELSE
> > > > BEGIN
> > > > -- Error handling
> > > > print 'No Update'
> > > > END
> > > > END
> > > > ELSE
> > > > BEGIN
> > > > -- Error Handling
> > > > print 'No free row'
> > > > END
> > > > Result:
> > > > select * from Locations
> > > > Location unused SomeOtherCol
> > > > ----------- ----------- ------------------------------
> > > > 1 1 FirstTran1
> > > > 2 1 SecondTran2
> > > > 3 0 Third
> > > > 4 0 Fourth
> > > > 5 0 Fifth
> > > > 6 0 Sixth
> > > > 7 0 Seventh
> > > > 8 0 Eighth
> > > > 9 0 Nineth
> > > > 10 0 Tenth
> > > > (10 row(s) affected)
> > > > Regards
> > > > AJ
> > > > "Tim B" <t...@innov8uk.com> wrote in message
> news:uFXk2ALYCHA.464@tkmsftngp12...
> > > > > Hi Andrew,
> > > > > if i put a WAITFOR DELAY '000:00:10' in the stored
> > > > > procedure between the select and the update, and then using two
> query
> panes
> > > > > run the store procedure, they both get the same result. I have
> tried
> > > > > setting the default to serializable but the second query gets chosen
> as
> a
> > > > > dead lock victim same occurs with repeatable read.
> > > > > Any ideas?
> > > > > Tim B
> > > > > "Andrew John" <a...@NOSPAMmistrose.com> wrote in message
> > > > > news:uDDRxZKYCHA.1792@tkmsftngp10...
> > > > > > Tim,
> > > > > > This may work:
> > > > > > set @location = NULL
> > > > > > select @location = (select top 1 Location from Locations with
> (READPAST)
> where unused = 0 order by Location)
> > > > > > IF @location is not NULL
> > > > > > BEGIN
> > > > > > update Locations with (holdlock) set used = 1 where location =
> @location
> > > > > > IF @@Rowcount = 1
> > > > > > -- Do other stuff
> > > > > > ELSE
> > > > > > BEGIN
> > > > > > -- Error handling
> > > > > > END
> > > > > > ELSE
> > > > > > BEGIN
> > > > > > -- Error Handling
> > > > > > END
> > > > > > Which is I think equivalent to the SERIALIZABLE isolation level.
> > > > > > Hope this helps
> > > > > > AJ
> > > > > > "Tim B" <t...@innov8uk.com> wrote in message
> news:#v$6ulJYCHA.1732@tkmsftngp10...
> > > > > > > Hi,
> > > > > > > trying to workout what transaction isolation level to use
> for
> the
> > > > > > > following extract of code from a Stored procedure
> > > > > > > select @location = (select Location from Locations where unused
> = 0)
> > > > > > > -- do other stuff
> > > > > > > update Locations set used = 1 where location = location
> > > > > > > If i use repeatable read then other users will not be able to
> update
> the
> > > > > > > same record if i have not yet updated but they may still get the
> same
> > > > > > > location(from the select) as i have not set the flag yet. I can
> replace
> the
...