简体   繁体   中英

Can I mark a database record as “in use”?

Let's say I have a table (let's call it myTable ) on a database server, and I'm writing a desktop client application that allows you to modify records in myTable. I don't want two users to be able to edit the same record, ie, if user A edits record 1 and user B tries to do the same, he gets notified that the record is currently "locked" by user A.

I'm sure that this is a common problem, so I'm wondering if there is a canonical solution to it.


There is an obvious solution, but it also has an obvious drawback:

  • Add a field inUseBy to myTable , set it to the user's name once the user starts editing the record, and clear it once the user finishes, eg

     function editRecord(recordId): begin transaction if (select lockedBy from myTable where id = recordId) is not empty: commit show "Sorry, record already in use by ..." else update myTable set lockedBy = current_user() where id = recordId commit show UI window to let user edit and update record update myTable set lockedBy = empty where id = recordId 

    Drawback: If user A's application crashes, the record stays locked.

The following approach might seem suitable at a first glance, but won't solve the problem:

  • Use database locks to lock record 1. This will just cause user B to run into a timeout. I need to lock the record on the application level not on the database level.

A common approach is to use ROWVERSION for optimistic concurrency.

Rowversion is a datatype (Which you'd add as a new column) that updates when the row is updated.

So, you select your row, including the rowversion column. When you send your update back, you make sure the rowversions match - By doing your update and adding "WHERE Rowversion = TheRowversionIGotEarlier" and seeing if @@ROWCOUNT is not 0 - If it is zero, then you can assume someone has modified the row since you read it, and you can return that message to the user.

http://www.mssqltips.com/sqlservertip/1501/optimistic-locking-in-sql-server-using-the-rowversion-data-type/

You're asking about pessimistic concurrency, and as this answer and the comment on your question say - Do consider optimistic concurrency. Consider your model, how would it handle someone starting to edit a record then going to lunch? Or if they never came back from lunch? What if a record has to be edited in the meantime, for a critical business reason?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM