473,386 Members | 1,644 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Concurrency Handling In Stored Procedures

I have a requirement that requires detection of rows deleted/updated by
other processes. My business objects call stored procedures to create,
read, update, delete data in a SQL Server 2000 data store. I've done
a fair amount of research on concurrency handling in newsgroups and
other resources. Below is what I've come up as a standard for
handling concurrency thru stored procedures. I am sharing with everyone
so I can get some comments (pro/con) regarding this approach and see if
anyone can find any holes for this solution.

Below is the DDL, DML and a Stored Proc demonstrating the approach. I
am using a rowversion column for concurrency checking. Another approach
that is less intrusive (doesn't require having a rowversion column in
all tables) is using checksum. I may eventually use checksum but the
process flow should be almost identical. Looking forward to anyone's
comments.

Thx, BZ

--xxxxxxxxxxxxxxxxxxxxxxxxxxx--

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'U' AND name =
'ApplicationUsers')
BEGIN
PRINT 'Dropping Table ApplicationUsers'
DROP Table dbo.ApplicationUsers
END
GO

PRINT 'Creating Table ApplicationUsers'
GO

CREATE TABLE dbo.ApplicationUsers
(
LoginName varchar (20) NOT NULL Primary Key,
LoginPassword varchar (50) NOT NULL,
LoginAttempts int NOT NULL default(0),
EmailAddress varchar(25) NOT NULL Unique,
DataVersion rowversion NOT NULL
)

GO
IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name =
'UpdateUser')
BEGIN
PRINT 'Dropping Procedure UpdateUser'
DROP Procedure dbo.UpdateUser
END

GO

PRINT 'Creating Procedure UpdateUser'
GO

Create Procedure dbo.UpdateUser
@loginName Varchar (20),
@loginPassword Varchar (50),
@loginAttempts Int,
@emailAddress Varchar(25),
@dataVersion Rowversion Output
As
/************************************************** ****************************
** Name: dbo.UpdateUser
** Desc: Updates an Application User instance
**
** Parameters:
** Input
** @loginName
** @loginPassword
** @loginAttempts
** @emailAddress
** @dataVersion. row version used for concurrency control.
**
** Output
** @dataVersion. updated row version used for concurrency
control.
**
** Return
** 0 for Success. Error code if any are encountered
** 66661 if current row version doesn't match provided version
** 66666 if expected row is not found
**

************************************************** *****************************/

Set NoCount On

Declare
@err Int,
@rowCount Int,
@tranCount Int

--Transaction Handling
Select @tranCount = @@TRANCOUNT
If (@tranCount=0)
Begin Tran LocalTran
Else
Save Tran LocalTran

Update
dbo.ApplicationUsers
Set
LoginPassword = @loginPassword,
LoginAttempts = @loginAttempts,
EmailAddress = @emailAddress
Where
LoginName = @loginName
And
DataVersion = @dataVersion

--Check for errors and rowCount (Should have updated 1 row)
Select @err = @@ERROR, @rowCount = @@ROWCOUNT
If (@err != 0) GOTO ErrHandler
If (@rowCount != 1) GOTO ConcurrencyHandler

--Set dataversion output parameter
Select
@dataVersion = DataVersion
From
dbo.ApplicationUsers
Where
LoginName = @loginName

/*
If we got this far then there were no errors
If this proc started transaction then commit it,
otherwise return and let caller handle transaction
*/
If (@TranCount = 0)
Commit Tran LocalTran

Return 0

/*
Rollback local transaction if an error was encountered.
Return code is used to communicate error number.
*/

--Handle Concurrency Errors
ConcurrencyHandler:
Rollback Tran LocalTran

If Exists (Select * From dbo.ApplicationUsers where LoginName =
@loginName)
Return 66661 --Row version doesn't match provided version
Else
Return 66666 --Row not found

--Handle Other Errors
ErrHandler:
Rollback Tran LocalTran

Return @err --Return Err Number

GO

PRINT 'Inserting Test Data...'

--Add Test Data
Insert Into dbo.ApplicationUsers
(LoginName, LoginPassword, LoginAttempts, EmailAddress)
Values
('blackmamba', 'Pwd1', default, 'b*@DIVAS.com')

Insert Into dbo.ApplicationUsers
(LoginName, LoginPassword, LoginAttempts, EmailAddress)
Values
('GoGo', 'Pwd2', default, 'g***@crazy88.com')

GO

/*

Call UpdateUser Stored Proc with current rowversion

*/
Declare @retVal int, @rowvrsn rowversion

--Get Current Row Version
select @rowvrsn = DataVersion from dbo.ApplicationUsers where LoginName
= 'blackmamba'

Exec @retVal = dbo.UpdateUser @loginName = 'blackmamba', @loginPassword
= 'UpdatedPwd', @loginAttempts = 0, @emailAddress = 'b*@DIVAS.com',
@dataVersion = @rowvrsn output

Print @retVal --Should be 0 for success

GO

/*

Call UpdateUser Stored Proc with out of date rowversion (simulate
update by other process)

*/
Declare @retVal int, @rowvrsn rowversion

--Get Current Row Version
select @rowvrsn = DataVersion from dbo.ApplicationUsers where LoginName
= 'blackmamba'

--Simulate update by other process
Update dbo.ApplicationUsers Set LoginPassword = LoginPassword where
LoginName = 'blackmamba'

--Update User with out of date Rowversion
Exec @retVal = dbo.UpdateUser @loginName = 'blackmamba', @loginPassword
= 'UpdatedPwdVersion2', @loginAttempts = 0, @emailAddress =
'b*@DIVAS.com', @dataVersion = @rowvrsn output

Print @retVal --Should be 66661 for rowversion mismatch

GO

/*

Call UpdateUser Stored Proc with out of date rowversion (simulate
delete by other process)

*/

Declare @retVal int, @rowvrsn rowversion

--Get Current Row Version
select @rowvrsn = DataVersion from dbo.ApplicationUsers where LoginName
= 'blackmamba'

--Simulate delete by other process
Delete From dbo.ApplicationUsers where LoginName = 'blackmamba'

--Update User with out of date Rowversion
Exec @retVal = dbo.UpdateUser @loginName = 'blackmamba', @loginPassword
= 'UpdatedPwdVersion2', @loginAttempts = 0, @emailAddress =
'b*@DIVAS.com', @dataVersion = @rowvrsn output

Print @retVal --Should be 66666 for row deleted by other process

Jul 23 '05 #1
2 5091
xAvailx (bj******@hotmail.com) writes:
Below is the DDL, DML and a Stored Proc demonstrating the approach. I
am using a rowversion column for concurrency checking. Another approach
that is less intrusive (doesn't require having a rowversion column in
all tables) is using checksum. I may eventually use checksum but the
process flow should be almost identical.


I would advice against using checksum. The checksum functions in SQL Server
are simple XOR, and the probability that two different rows are not
detected is not negligible.

rowversion is fine.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 23 '05 #2
Thanks for the checksum vs rowversion feedback, Erland.

Do you see any issues/gotchas with the implementation?

Thx, BZ

Jul 23 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: dtwilliams | last post by:
OK, i'm trying to do some error checking on stored procedures and am following the advise in Erland Sommarskog's 'Implementing Error Handling with Stored Procedures' document. Can anybody help...
5
by: Steve | last post by:
Visual Studio 2003 .Net / C# / SQL 2000 I am trying to work out the best way to ensure data concurrency in my application. All updates and inserts etc are done via stored procedures. When a...
7
by: mybappy | last post by:
Hi: I am trying to use timestamp field of SQL Server to maintain concurrency. My problem is how do I store the timestamp value in my webform. The hidden field does not work as I get some cast...
5
by: Bari Allen | last post by:
I'm trying to test for concurrency, using a SQL Stored Procedure on a RowVersion (timestamp) Field. The vb code I'm using is as follows Dim cmd As New SqlCommand("ConcurrencyCheck", cn) Dim...
5
by: Jurgen Defurne | last post by:
I am currently designing an application which should be accessible from different interfaces. For this I like to be using stored procedures to process the contents of form submissions and dialog...
0
by: balaji krishna | last post by:
Hi, I need to handle the return set from COBOL stored procedure from my invoking Java program. I do not know, how many rows the stored proc SQL fetches.I have declared the cursor in that proc, but i...
1
by: pob | last post by:
>From a form I have some code that calls 4 modules frmMain 1 mod 2 mod 3 mod 4 mod If mod 1 experiences an error the error handling works fine within mod 1 and writes out the error to a...
5
by: John | last post by:
Hi I have developed the following logic to handle db concurrency violations. I just wonder if someone can tell me if it is correct or if I need a different approach.Would love to know how pros...
7
by: John | last post by:
Hi I have asked this question before but have not received any clear answer. I have a winform app with bound controls via dataadapter/dataset combination.I have a dbconcurrency exception ex. Now...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.