http://qs1969.pair.com?node_id=593679

oyse has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am implementing a web-application where more than one user can access the same row at the same time. This can lead to problems, since one user might update the row while the other users look at old data. They might make updates of the old data, thereby overwriting the changes of the first user. To prevent this problem I want to implement some kind of row locking at the application level.

The way I plan to implement the locking is by creating a table in the database that contains information about all the locked rows. When a user wants to view a row, I will check if it is locked by looking in the table. It the row is not locked the user will acquire a lock on the row.

The algorithm as I see it will contain a race condition since I will first check if the row is locked using a SELECT query, if it is not locked a row will be inserted using an INSERT query. The race conditon happens if two http requests manages to check the table before one of them inserts/acquires the lock.

To solve the race condition, I plan to use transactions in DBI like this:

1. turn of autocommit
2. check if the row is locked (check the lock table)
3. if it is not locked, lock the row (insert a row in the lock table)
4. commit
5. turn on autocommit (since the rest of the application uses it)

I think this algorithm will work, but it will take me some time to implement and test. So before I start implementing it, it would be nice to know if any CPAN modules will do this for me?

Secondly, do you think the algorithm will prevent the race condition?