Solved

Need to prevent race condition during select and update

Posted on 2001-08-07
6
617 Views
Last Modified: 2012-06-27
I am using SQL Server 6.5 and I have a stored procedure that creates a sales number by incrementing the last one used.
I store that information in a table called  LastSalesNumber.  This function worked fine for over a
year but I am now having problems with an increase in traffic and users.  I have had at least two occasions where it appears that two users made sales at the very same time and two different sales records were created with the same number.  What changes should I make to the following code in the form of locking or restructuring to ensure that this doesn't happen anymore?


-- begin snippet
/* Assign Sales number to be last sales number assigned + 1  */

select @SalesNumber = "SLS-" + convert(varchar(13), LastNumber + 1)
     from LastSalesNumber


/*  increment the last Sales number assigned  */

update LastSalesNumber
     set LastNumber = LastNumber + 1

-- end snippet
0
Comment
Question by:geowilli
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 75

Expert Comment

by:Anthony Perkins
ID: 6362123
Since there is no implict row locking in SQL Server 6.5 you may want to try reversing the statements:

In other words, update first
update LastSalesNumber
    set LastNumber = LastNumber + 1

And then Select:
select @SalesNumber = "SLS-" + convert(varchar(13), LastNumber)
    from LastSalesNumber

Here the problem may be the reverse: "gaps" in your sales numbers.
0
 
LVL 143

Accepted Solution

by:
Guy Hengel [angelIII / a3] earned 50 total points
ID: 6362684
The problem is atomicity, which can be solved using transactions:

begin transaction
/* Assign Sales number to be last sales number assigned + 1  */

select @SalesNumber = "SLS-" + convert(varchar(13), LastNumber + 1)
    from LastSalesNumber


/*  increment the last Sales number assigned  */

update LastSalesNumber
    set LastNumber = LastNumber + 1

commit transaction


This will make that if a first user is inside this transaction, any other user will have to wait until that one has finished. Using your code, they can immediately go on...

Cheers
0
 
LVL 18

Expert Comment

by:nigelrivett
ID: 6362843
Unfortunately with this code there is nothing to stop two spids getting the same sales number as

select @SalesNumber = "SLS-" + convert(varchar(13), LastNumber + 1)
   from LastSalesNumber

will take a shared lock which is compatible with another shared lock and the lock will be released immediately.
Code that will work is

update LastSalesNumber
set LastNumber = LastNumber + 1 ,
@SalesNumber = "SLS-" + convert(varchar(13), LastNumber + 1)

or
begin tran
update LastSalesNumber
   set LastNumber = LastNumber + 1

select @SalesNumber = "SLS-" + convert(varchar(13), LastNumber)
from LastSalesNumber
commit tran

commit transaction
0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 18

Expert Comment

by:nigelrivett
ID: 6362847
update LastSalesNumber
   set LastNumber = LastNumber + 1

select @SalesNumber = "SLS-" + convert(varchar(13), LastNumber)
   from LastSalesNumber

This doesn't work either without the transaction as two spids could do the update before both getting the same number.
0
 
LVL 1

Author Comment

by:geowilli
ID: 6364721
Thanks for the answer and brief explanation
0
 
LVL 18

Expert Comment

by:nigelrivett
ID: 6364830
um.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Slowly Changing Dimension Transformation component in data task flow is very useful for us to manage and control how data changes in SSIS.
Ever wondered why sometimes your SQL Server is slow or unresponsive with connections spiking up but by the time you go in, all is well? The following article will show you how to install and configure a SQL job that will send you email alerts includ…
Using examples as well as descriptions, and references to Books Online, show the different Recovery Models available in SQL Server and explain, as well as show how full, differential and transaction log backups are performed
Viewers will learn how the fundamental information of how to create a table.

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question