samedi 26 mai 2012

MySQL table lock with Django

When operating with a relational database like MySQL or PostgreSQL it is sometimes required to use table locks, usually when performing a transaction susceptible to concurrency problems.

As a rule of thumb:
  - a WRITE LOCK on a table is needed when writing to that table while performing a transaction susceptible to concurrency issues,
  - a READ LOCK on a table is needed when reading from that table while performing a transaction susceptible to concurrency issues,
  - when a lock is acquired, all the tables used in the transaction must be locked,
  - all locks must be released when a database transaction is completed.

Django's ORM doesn't have support for table locks, which is quite understandable as table locking is database specific.

I wrote a small context manager that can be used to lock tables with MySQL:

It works with the models declared in your django application, by simply providing two lists:
  - the list of models to lock for read purposes, and
  - the list of models to lock for write purposes.

For instance, using django tutorial's models, you would just call the context manager like this:

with acquire_table_lock(read=[models.Poll], write=[models.Choice]):
    # Do something here
    pass