python django事务transaction源码分析
生活随笔
收集整理的這篇文章主要介紹了
python django事务transaction源码分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
python Django事務
網上關于django1.6的事務資料很多,但是1.8的卻搜不到任何資料,自己要用的時候費了不少勁就是不行,現在記下要用的人少走彎路 version:Django 1.8 事務官方文檔 事務中文文檔 里面介紹很多方法,不一一贅述,按照文檔即可,下面只分析下atomic方法的源碼 按照官方文檔 transaction.atomic 有兩種用法裝飾器和上下文管理器
# atomic() 方法 # from django.db import transaction ################### # atomic() ################### def atomic(using=None, savepoint=True): # 裝飾器和上下文管理器必須.()調用方法,因為真正的處理是該方法返回的實例,不是該方法本身if callable(using):return Atomic(DEFAULT_DB_ALIAS, savepoint)(using)# Decorator: @atomic(...) or context manager: with atomic(...): ...else:return Atomic(using, savepoint) ########################################## # Atomic類 省略了非核心內容 ############################################ class Atomic(ContextDecorator):def __init__(self, using, savepoint):self.using = usingself.savepoint = savepointdef __enter__(self):connection = get_connection(self.using)sid = connection.savepoint() # 進入with創建一個保存點# .............dodef __exit__(self, exc_type, exc_value, traceback):if connection.in_atomic_block:# do.............if sid is not None:try:connection.savepoint_commit(sid) # 提交事務except DatabaseError:try:connection.savepoint_rollback(sid) # 捕獲數據庫異常回滾connection.savepoint_commit(sid)except Error:connection.needs_rollback = Trueraise## 還有一段代碼是exec_type收到其他程序異常時候 全局回滾,此處省略# do................. ############################### # ContextDecorator ################################# class ContextDecorator(object):def __call__(self, func):def inner(*args, **kwargs):with self: # 把函數放進self的with上下文管理器,效果with相同,只是控制細粒度不同return func(*args, **kwargs)return innerpython MySQLdb
class Tran():def __init__(self, conn=None, close=True):if conn is None: # 創建數據庫鏈接print 'init'self.conn = conn_tbkt()self.cur = self.conn.cursor()self.sql = []def __enter__(self): # 上下文管理器返回 sql語句列表 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 # 執行sqlfor s in self.sql:self.cur.execute(s)self.conn.commit()except: # 可以捕獲所有異常(django事務如果中間出現程序異常終止無法回滾)try: # 回滾本身也是sql執行,也有可能失敗import tracebacktraceback.print_exc()print 'rollback'self.conn.rollback()except:print u'回滾失敗'finally:self.cur.close()self.conn.close()更細粒度的回滾:
# 在事務塊中@atomic() 或者 with atomic(): sid = transaction.savepoint('tbkt_pxb') try:# do .......... except:transaction.savepoint_rollback(sid, 'tbkt_pxb')注意:如果有多個數據庫有路由,則需要指定和路由返回一致的useing: math2下的model需要事務,即使ziyuan_new和default是同一個庫,也必須使用useing=ziyuan_new
ziyuan_app = ['math2', 'ziyuan']if model._meta.app_label in ziyuan_app:return "ziyuan_new"return 'default'調用時候必須.()方法調用
atomic塊中必須注意try的使用,如果手動捕獲了程序錯誤會導致atomic包裝器捕獲不到異常,也就不會回滾。要么try內代碼不影響事務操作,要么就捕獲異常后raise出,讓atomic可以正常回滾(就是因為沒有注意到這個問題,導致嘗試了好幾天都沒成功,切記)
轉載于:https://my.oschina.net/watcher/blog/718449
總結
以上是生活随笔為你收集整理的python django事务transaction源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: httpd-2.2和httpd-2.4虚
- 下一篇: button按钮无法提交表单问题发现与解