python django transaction transaction source code analysis

  • 2020-05-27 06:05:13
  • OfStack

python Django transaction

A lot of affairs information online about django1. 6, but it can't search any information, 1.8 you want to use is not a lot of trouble, now take note to use fewer detours version: Django 1.8 affairs official document transaction documents in Chinese introduce a lot of ways, not 11, according to the document, the following only atomic analysis method of source according to the official documentation transaction. atomic has two USES decorators and context manager


# atomic()  methods  
# from django.db import transaction
###################
# atomic()
###################
def atomic(using=None, savepoint=True): #  Decorators and context managers must .() Call the method, because the actual processing is the instance that the method returns, not the method itself 
 if callable(using):
  return Atomic(DEFAULT_DB_ALIAS, savepoint)(using)
 # Decorator: @atomic(...) or context manager: with atomic(...): ...
 else:
  return Atomic(using, savepoint)
##########################################
# Atomic class   The non-core content is omitted 
############################################
class Atomic(ContextDecorator):
 def __init__(self, using, savepoint):
 self.using = using
 self.savepoint = savepoint
 def __enter__(self):
 connection = get_connection(self.using)
 sid = connection.savepoint()   #  Enter the with create 1 A savepoint 
 # .............do
 def __exit__(self, exc_type, exc_value, traceback):
 if connection.in_atomic_block:
 # do.............
 if sid is not None:
  try:
   connection.savepoint_commit(sid)  #  Commit the transaction 
  except DatabaseError:
   try:
    connection.savepoint_rollback(sid) #  Catch database exception rollback 
    connection.savepoint_commit(sid)
   except Error:
    connection.needs_rollback = True
   raise
 ##  There are 1 Code is exec_type When receiving other program exceptions   Global rollback, omitted 
 # do.................
###############################
# ContextDecorator
#################################
class ContextDecorator(object):
 def __call__(self, func):
  def inner(*args, **kwargs):
   with self:    #  Put the function in self the with Context manager, effects with Same, but with different control granularity 
    return func(*args, **kwargs)
  return inner

python MySQLdb


class Tran():
 def __init__(self, conn=None, close=True):
  if conn is None:     #  Create a database link 
   print 'init'
   self.conn = conn_tbkt()
   self.cur = self.conn.cursor()
   self.sql = []

 def __enter__(self):       #  The context manager returns  sql The statement list  with Tran('tbkt_pxb') as sqls:
  print 'enter'
  return self.sql  # sql.append('select 1')

 def __exit__(self, exc_type, exc_val, exc_tb):
  print 'exit'
  try:

   print self.sql        #  perform sql
   for s in self.sql:
    self.cur.execute(s)
   self.conn.commit()
  except:            #  All exceptions can be caught (django The transaction cannot be rolled back if there is an abnormal program termination in the middle )
   try:     #  So is the rollback itself sql Execution may also fail 
    import traceback
    traceback.print_exc()
    print 'rollback'
    self.conn.rollback()
   except:
    print u' Roll back the failure '
  finally:
   self.cur.close()
   self.conn.close()

More fine-grained rollback:


#  In the transaction block @atomic()  or  with atomic():
sid = transaction.savepoint('tbkt_pxb')
try:
 # do ..........
except:
 transaction.savepoint_rollback(sid, 'tbkt_pxb')

Note: if there are multiple databases with routes, you need to specify and route back 1 to useing: model under math2 requires a transaction, even if ziyuan_new and default are the same library, you must use useing=ziyuan_new


  ziyuan_app = ['math2', 'ziyuan']
  if model._meta.app_label in ziyuan_app:
   return "ziyuan_new"

  return 'default'

Must.() method call

Note the use of try in the atomic block. If you manually catch a program error, the atomic wrapper will not catch the exception and will not roll back. Either the code in try does not affect the transaction operation, or the exception is caught and raise is out so that atomic can roll back normally (just because you didn't notice the problem, you failed for several days, remember).

Thank you for reading, I hope to help you, thank you for your support of this site!


Related articles: