Python django transaction source code analysis, djangotransaction
Python Django transactions
There are a lot of online transaction information about django1.6, but 1.8 cannot find any information. If you have to use it for a long time, you will not be able to use it. Now you can write down the version with fewer detours: many methods are introduced in the Chinese documents of Django 1.8 official transactions. Do not repeat them one by one. Follow the instructions below to analyze only the source code of the atomic method according to the official documents transaction. there are two ways to use atomic: decorator and context manager.
# Atomic () method # from django. db import transaction ################### atomic () ################## def atomic (using = None, savepoint = True): # required for decorator and context manager. () call the method, because the actual processing is the instance returned by the method, 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) ######################################## ### non-core content is omitted in the Atomic class ############################### ############ 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 with to create a save point #............. 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 commit t DatabaseError: try: connection. savepoint_rollback (sid) # Capture Database exceptions and roll back the connection. savepoint_commit (sid) failed T Error: connection. needs_rollback = True raise # Another piece of code is exec_type, which is global rollback when other program exceptions are received, skipped here # do ................. ############################### ContextDecorator ####### ######################### class ContextDecorator (object): def _ call _ (self, func): def inner (* args, ** kwargs): with self: # Put the function into the with context manager of self, the results are the same as those of with, but different 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 the SQL 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 'eg' try: print self. SQL # Execute SQL for s in self. SQL: self.cur.exe cute (s) self. conn. commit () commit T: # All exceptions can be caught (if a program exception occurs in the middle of a django transaction, it cannot be rolled back) try: # rollback itself is also an SQL Execution, it may also fail to import traceback. print_exc () print 'rollback' self. conn. rollback () failed T: print u'rollback failed' finally: self. cur. close () self. conn. close ()
More fine-grained rollback:
# @ Atomic () or with atomic (): sid = transaction in the transaction block. savepoint ('tbkt _ pxb') try: # do .......... counter T: transaction. savepoint_rollback (sid, 'tbkt _ pxb ')
NOTE: If multiple databases have routes, You need to specify the useing that is the same as that returned by the route: the model under math2 requires a transaction, even if ziyuan_new and default are the same database, you must also use useing = ziyuan_new
ziyuan_app = ['math2', 'ziyuan'] if model._meta.app_label in ziyuan_app: return "ziyuan_new" return 'default'
The. () method is required for call.
Note the use of try in the atomic block. If a program error is manually captured, the atomic package cannot catch the exception and will not roll back. Either the code in try does not affect the transaction operation, or raise will be caught after the exception, so that the atomic can be rolled back normally (that is, due to the failure to notice this problem, it has failed for several days, remember)
Thank you for reading this article. I hope it will help you. Thank you for your support for this site!