How to perform table/row locks in Django

淺唱寂寞╮ 提交于 2019-12-07 04:48:24

问题


In production environments where Django is running on Apache or with multiple Gunicorn workers, it runs the risk of concurrency issues.

As such, I was pretty surprised to find that Django's ORM doesn't explicitly support table/row locking. It supports transactions very handedly, but that only solves half of the concurrency problem.

With a MySQL backend, what is the correct way to perform locking in Django? Or is there something else at play in Django's framework that makes them unnecessary?


回答1:


Django does not explicitly provide an API to perform table locking. In my experience, well-designed code rarely needs to lock a whole table, and most concurrency issues can be solved with row-level locking. It's an last-ditch effort: it doesn't solve concurrency, it simply kills any attempt at concurrency.

If you really need table-level locking, you can use a cursor and execute raw SQL statements:

from django.db import connection

with connection.cursor() as cursor:
    cursor.execute("LOCK TABLES %s READ", [tablename])
    try:
        ...
    finally:
        cursor.execute("UNLOCK TABLES;")



回答2:


Consider setting the transaction isolation level to serializable, and using a MySQL table type that supports transactions (MyISAM does not, InnoDB does.)

After ensuring you have a backend that supports transactions, you'd then need to disable autocommit (https://docs.djangoproject.com/en/1.8/topics/db/transactions/#autocommit-details) and then ensure that your code issues the appropriate commit or rollback statement at the end of what you consider to be transactions.

There is an example or two in the above referenced docs..

Doing this requires a bit more work and consideration, but provides you with transactions.



来源:https://stackoverflow.com/questions/33693862/how-to-perform-table-row-locks-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!