This famous problem is known as a "lost update"
Each of the instances of the component performs the following steps:
1. Read an integer X from a database.
2. Add 10 to X.
3. Write the new value of X to the database.
If each these three steps exceutes together in an atomic operation, everthing
is fine. Neither instance can interfere with the other instance's operations.
Remember, though, that the thread-scheduling algorithm being used in the
backgroud does not guarentee this. If two instances are executing these three
operations, the operations could be interleaves. The follwing order of operations
1. Instance A reads integer X from database. The database now contains X = 0.
2. Instance B reads integer X from database. The database now contains X = 0.
3. Instance A adds 10 to its copy of X and persists it to the database. The
database now contains X = 10.
4. Instance B adds 10 to its copy of X and persists it to the database. The
database now contains X = 10;
What happened here? Due to the interleaving of database operations, instance
B is working with a stale copy of X: The copy before instance A performed a
write. Thus, instance A's operations have been lost! This famous problem is
known as a "lost update". It is very serious situation-instance B has been
working with stale data and has overwritten instance A's write. How can
transactions avoid this scenario?
The solution to this problem is to use "locking" on the database to prevent the
two components from reading data. By locking the data your transaction is using,
you guarantee that your transaction and only your transaction has access to
that data until you release that lock. This prevents interleaving of sensitive
In our scenario, if our component acquired an exclusive lock before the trans-
action began and released that lock after the transaction, then no interleaving
would be possible.
1. Request a lock on X.
2. Read an integer X from a database.
3. Add 10 to X.
4. Write then new value of X to the database.
5. Release the lock on X.
If another component ran concurrently with ours, that component would have to
wait until we relinguished our lock, which would give that component our
fresh copy of X.