class LockingManager(models.Manager):
""" Add lock/unlock functionality to manager.
Example::
class Job(models.Model): #其实不用这么负载,直接在orm创建表的时候,给这个表定义一个lock和unlock方法,借助django提供的connection模块来发送锁表的原生sql语句和解锁的原生sql语句就可以了,不用外层的这个LckingManager(model.Manager)类
manager = LockingManager()
counter = models.IntegerField(null=True, default=0)
@staticmethod
def do_atomic_update(job_id)
''' Updates job integer, keeping it below 5 '''
try:
# Ensure only one HTTP request can do this update at once.
Job.objects.lock()
job = Job.object.get(id=job_id)
# If we don't lock the tables two simultanous
# requests might both increase the counter
# going over 5
if job.counter < 5:
job.counter += 1
job.save()
finally:
Job.objects.unlock()
"""
def lock(self):
""" Lock table.
Locks the object model table so that atomic update is possible.
Simulatenous database access request pend until the lock is unlock()'ed.
Note: If you need to lock multiple tables, you need to do lock them
all in one SQL clause and this function is not enough. To avoid
dead lock, all tables must be locked in the same order.
See http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
"""
cursor = connection.cursor()
table = self.model._meta.db_table
logger.debug("Locking table %s" % table)
cursor.execute("LOCK TABLES %s WRITE" % table)
row = cursor.fetchone()
return row
def unlock(self):
""" Unlock the table. """
cursor = connection.cursor()
table = self.model._meta.db_table
cursor.execute("UNLOCK TABLES")
row = cursor.fetchone()
return row
from django.db import 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 viewfunc(request): # This code executes inside a transaction. do_stuff()
用法2:作为上下文管理器来使用,其实就是设置事务的保存点
from django.db import transactiondef viewfunc(request): # This code executes in autocommit mode (Django's default). do_stuff() with transaction.atomic(): #保存点 # This code executes inside a transaction. do_more_stuff() do_other_stuff()
@transaction.atomicdef viewfunc(request): a.save() # open transaction now contains a.save() sid = transaction.savepoint() #创建保存点 b.save() # open transaction now contains a.save() and b.save() if want_to_keep_b: transaction.savepoint_commit(sid) #提交保存点 # open transaction still contains a.save() and b.save() else: transaction.savepoint_rollback(sid) #回滚保存点 # open transaction now contains only a.save() transaction.commit() #手动提交事务,默认是自动提交的,也就是说如果你没有设置取消自动提交,那么这句话不用写,如果你配置了那个AUTOCOMMIT=False,那么就需要自己手动进行提交。