How to RowLock in a Stored Proc?

Hi All.

 i have some C# code that basically calls two stored procs.

pseudo code

objThing.Get()  -> this calls stored proc usp_Thing_Get, which is a basic SELECT *

objThing.Money = 100 + intNewAmount;

objThing.Set()  -> this calls stored proc usp_THING_Set, which UPDATES a row.


now, i need to lock the row in the GET, and then UNLOCK IT after i do a set ....

any suggestions please?  i have NO idea how this can be done :(

thanks in advance.
LVL 1
pure032398Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ShogunWadeCommented:
You should not do it in this way.

Assuming that "pseudo code" is actually pretty much what you want to do, then what you ort to be doing is encapsulating all of this functionality in a single stored procuedre wrapped in a transaction.
0
BAlexandrovCommented:
objThing.BeginTransaction()
...
objThing.Commit()
0
wsteegmansCommented:
Indeed, you could use a Transaction for your problem. When starting a Transaction (BeginTransaction) you can specify the Isolationlevel. So, here you set who can view/change recordfields of a LOCKED record ...

Using Transactions is very simple, ... transactions offer the developer the ability to enforce data integrity by making sure multiple operations can be treated by the engine as an "all or nothing" proposition, thereby never allowing the database to end up in an inconsistent state.

Some code?
I think you have here a nice story:
http://www.c-sharpcorner.com/asp/Code/TransactionsInASPNETDPL.asp

Look also in the MSDN ...

You could also do it on SQL-Server level, with the <table_hint> part in the FROM clause:

Table Hint Syntax

SYNTAX
[ FROM { < table_source > } [ ,...n ] ]

< table_source > ::=
    table_name [ [ AS ] table_alias ] [ WITH ( < table_hint > [ ,...n ] ) ]
   
< table_hint > ::=
    { INDEX ( index_val [ ,...n ] )
        | FASTFIRSTROW
        | HOLDLOCK
        | NOLOCK
        | PAGLOCK
        | READCOMMITTED
        | READPAST
        | READUNCOMMITTED
        | REPEATABLEREAD
        | ROWLOCK
        | SERIALIZABLE
        | TABLOCK
        | TABLOCKX
        | UPDLOCK
        | XLOCK
    }

There are fifteen hints defined in this syntax listing. Thirteen of these hints (HOLDLOCK, NOLOCK, PAGLOCK, READCOMMITTED, READPAST, READUNCOMMITTED, REPEATABLEREAD, ROWLOCK, SERIALIZABLE, TABLOCK, TABLOCKX, UPDLOCK, XLOCK) are considered table-level.
More info: http://www.sql-server-performance.com/rd_table_hints.asp

But, because you call two SPs seperately? I don"t know if this second part will work?
Why not building ONE stored procedure with all the logic and passing parameters ...? It makes things more simple!
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

pure032398Author Commented:
the reason i have two stored procs, is becuase i could do multiple calculations between the GET (select *) and the SET (update ).

i do not wish to pass the calcualtions to the SP becuase under certain curcumstances, it could be very complex - i need to keep the business logic on one Tier, and the Data on another.

the second reason i didn't mention transactions was becuase i do not know much about them -AND- i wasn't sure that if begin a transaction, this ROW LOCKS the data i am after.

why am i so interested in this row locking?

i have a multithreaded game which needs to make sure the data is always consisent.

i know that if i can LOCK a row when i read it (becuase i'm about to change the data), then i'm 100% sure than any other threads that wish to access this row will wait (or timeout) until it's unlocked.

i do not want to have two threads read the same data, and update the same row with different data.  I also do not wish to do some timestamp comparrison on the table / row, becuase then i need to do MORE work to re-read the data, then re-calc, then update ... and i could get could in an infinite loop as many threads are all fighting for the same row, etc.
0
pure032398Author Commented:
a further question relating to a comment above...

if i use transactions, could that row lock between the start and the commit?

eg.

// Somehow knows to lock row #10 (for example)
objThing.BeginTransaction()

// some business logic / calculations here ...
eg. intHealth += 10;   // very simple example, but can be very complex here...

objThing.Commit()
// Row now updated _AND_ unlocked.

??? is this the idea?
0
Anthony PerkinsCommented:
Please maintain these old open questions:

1 07/28/2003 60 How to Serialize two (different) instanc...  Open C#
2 07/20/2003 450 How to maintain Data Integrity with our ...  Open C#

Thanks,
Anthony
0
pure032398Author Commented:
Anthony  - those previous posts/open questions are maintained / updated.


now back to the topic ....

can stored_procs manually lock and unlock a row, or does this have to be asked elsewhere?
0
Anthony PerkinsCommented:
>> those previous posts/open questions are maintained / updated.<<
Thanks, I appreciate it.

Anthony
0
Scott PletcherSenior DBACommented:
You can explicitly specify locking using "hints" to increase the locking level from shared to exclusive, which will prevent anyone else from reading the row until you're done *if done as part of transaction*:

BEGIN TRAN

SELECT ...
FROM ... WITH (ROWLOCK, XLOCK)
WHERE ...

UPDATE ...
SET ...

END TRAN


I think, but am not sure, that XLOCK was added in SQL 2K; if so, naturally it won't work if your db is 7.0.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ShogunWadeCommented:
As I and others have said.   Perform a transaction.  If you dont want to make this one stored proc (which is the sensible thing) then at least put a transaction on connection object!
0
pure032398Author Commented:
I figured this out last night .. but yeah, the XLOCK was the answer.

becuase i'm not using one stored proc, because my business logic has to be handled in my C# code, using an ADO.Net Transaction works perfectly.

0
pure032398Author Commented:
One other thing relating to the Accepted Answer -> i found the XLOCK solution becuase i saw some documentation for 'WITH UPDATE" in some Sql doco..

how does WITH UPDATE differ from XLOCK?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft SQL Server

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.