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!