سؤال

Let's say that I have a controller with a method "UpdateRecord(int recordID)". This method is supposed to update given record only once (by setting appropiate value to record in database, let's say it's column "IsLock"). To check it I do:

  1. Download record with given recordID from database.
  2. Check if record has "IsLock" value set to FALSE.
  3. If IsLock == FALSE - update record in database and set IsLock to TRUE, otherwise - do not update and return error.

So now I wonder what happens if I do two AJAX request to this method (with the same recordID) one ofter another. Will ASP.NET execute second request only after first request is executed? Or will it execute both simultaneously?

To clarify even more please tell me whether this scenario is possible:

  1. I do first request (recordID = 555).
  2. One milisecond later I do second request (recordID = 555).
  3. First request downloaded record with given recordID = 555, checked that IsLock = FALSE, so it began preparing query to update record.
  4. Second request downloaded record with given recordID = 555, checked that IsLock = FALSE, so it began preparing query to update record (IsLock is stilL FALSE, because first request didn't have enough time to update database).
  5. First request successfully updated record.
  6. Second request successfully updated record (but it should return error because one record can be updated only once).

If is is possible, please tell mi how can I secure my method to prevent this scenario from happening?

هل كانت مفيدة؟

المحلول

First of all, it is defined not only by your application but also by IIS settings. I think this article will help.

To answer the ADO.net part - there are several types of data concurrency control, you can read here (Data Concurrency in ADO.NET) about difference and use one that is appropriate in your case.

In your case with locks you are going to change your query from

update T set IsLock = 1 where recordID = 555

to

update T set IsLock = 1 where recordID = 555 and IsLock = 0

and check return value of cmd.ExecuteNonQuery() to be 1 or 0.

In case it returned 0 record was not updated and lock was set by another user etc.

You might also want to add LockerID field to your table so your query going to be

update T set IsLock = 1, LockerID = @userID where recordID = @recordID and IsLock = 0

So when opening record you would first execute your lock query and if it was successful you will load record and show edit mode, otherwise show read-only mode.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top