Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement pessimistic locking in a php/mysql web application?

How to implement pessimistic locking in a php/mysql web application?

  1. web-user opens a page to edit one dataset (row)
  2. web-user clicks on the button "lock", so other users are able to read but not to write this dataset
  3. web-user makes some modifications (takes maybe 1 to 30 minutes)
  4. web-user clicks "save" or "cancel" and the "lock" is removed

Are there standard methods in php/mysql for this scenario? What happens if the web-user never clicks on "save"/"cancel" but closes the internet-exploror?

like image 429
user1027167 Avatar asked Nov 17 '11 16:11

user1027167


People also ask

Does MySQL support pessimistic locking?

MySQL supports pessimistic locking by default. Now TiDB also supports pessimistic locking, so MySQL users don't need to modify much application code to get started with TiDB.

What is pessimistic locking in MySQL?

There are two models for locking data in a database: Optimistic locking , where a record is locked only when changes are committed to the database. Pessimistic locking , where a record is locked while it is edited.

How do you achieve optimistic locking?

In order to use optimistic locking, we need to have an entity including a property with @Version annotation. While using it, each transaction that reads data holds the value of the version property. Before the transaction wants to make an update, it checks the version property again.


2 Answers

You need to implement a LOCKDATE and LOCKWHO field in your table. Ive done that in many applications outside of PHP/Mysql and it's always the same way.

The lock is terminated when the TTL has passed, so you could do a substraction of dates using NOW and LOCKDATE to see if the object has been locked for more than 30 minutes or 1h as you wish.

Another factor is to consider if the current user is the one locking the object. So thats why you also need a LOCKWHO. This can be a user_id from your database, a session_id from PHP. But keep it to something that identifies a user, an ipaddress is not a good way to do it.

Finaly, always think of a mass-unlock feature that simply resets all LOCKDATEs and LOCKWHOs...

Cheers

like image 179
Mathieu Dumoulin Avatar answered Nov 06 '22 23:11

Mathieu Dumoulin


I would write the locks in one centralized table instead of adding fields to all tables.

Example table structure :

tblLocks

  • TableName (The name of tha locked table)
  • RowID (Primary key of locked table row)
  • LockDateTime (When the row was locked)
  • LockUser (Who locked the row)

With this approach you can find all locks that are made by a user without having to scan all tables. You could kill all locks when user logs out for example.

like image 31
Benoit Gauthier Avatar answered Nov 06 '22 23:11

Benoit Gauthier