In addition to what Michael Green has pointed out in his excellent answer, you should also be aware of optimistic concurrency which is an application-level technique in a database that is used to guard against two users (or processes) attempting to modify the same piece of data. The technique is used when there is a low, but non-zero chance of two updates being made to a single piece of data. It's a similar scenario, conceptually at least, to a race condition, but it's not identical and it doesn't call for the same handling, so the techniques that an OS might use can't be applied in exactly the same way to an application database.
The scenario is that two users, for example Bob and Jane, read a customer record in the database. They both see the same version of the record. Then Bob saves a change, let's say to a customer's address on that record. A little bit latter, Jane saves a different change, let's say to the customer's credit limit. Since Jane didn't know about Bob's change, Jane's change overwrites Bob's, causing Bob's changes to be lost.
At the application level, you can protect against this scenario a couple of different ways. One is to re-read all of the data just before saving changes to make sure that it hasn't been changed since the last time it was read. This is a little bit onerous if the record has a lot of fields. A second way is to use a single field in each record as a sentinel that is updated every time anyone saves a change to a record. You could do this with something like a last_modified_datetime
field, but depending on how actively records are updated this may not be precise enough. Many RDBMSs have a feature to help with this. SQL Server, for example has a data type called ROWVERSION
(formerly TIMESTAMP
) which is a system-generated binary field that is automatically modified by the database every time a record is updated.
To be sure that Bob had not swooped in and modified the data out from under Jane, she would write her update
statement to including something like: ...WHERE CustomerID=@CustID AND CustRowVersion=@LastModRowVersion
(*)
Jane checks the count of affected rows for her update statement and if the number is 0 she knows that Bob (i.e. someone else) has been up to his old tricks and she needs to refresh her view of the data and reapply her changes.
Why use optimistic concurrency at the application level? You could instead use pessimistic concurrency and not let Jane read the record while Bob has it locked. Some systems will be built this way instead. The issue is one of design choice and user requirements. Optimistic concurrency is used when the chance of a collision is smaller than the chance of two people using the same record at the same time. For example, let's say Bob only wants to read (not update) the customer's address. In that case, why lock the record and prevent Jane from doing her job and modifying the customer's credit limit?
(*) these are terrible field/variable names, I'm not suggesting you use such bad names!