python django事务transaction源码分析详解


Posted in Python onMarch 17, 2017

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 = using
 self.savepoint = savepoint
 def __enter__(self):
 connection = get_connection(self.using)
 sid = connection.savepoint()   # 进入with创建一个保存点
 # .............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)  # 提交事务
  except DatabaseError:
   try:
    connection.savepoint_rollback(sid) # 捕获数据库异常回滚
    connection.savepoint_commit(sid)
   except Error:
    connection.needs_rollback = True
   raise
 ## 还有一段代码是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 inner

python 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        # 执行sql
   for s in self.sql:
    self.cur.execute(s)
   self.conn.commit()
  except:            # 可以捕获所有异常(django事务如果中间出现程序异常终止无法回滚)
   try:     # 回滚本身也是sql执行,也有可能失败
    import traceback
    traceback.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可以正常回滚(就是因为没有注意到这个问题,导致尝试了好几天都没成功,切记)

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Python 相关文章推荐
理解Python中的With语句
Mar 18 Python
windows下Python实现将pdf文件转化为png格式图片的方法
Jul 21 Python
用Python写王者荣耀刷金币脚本
Dec 21 Python
python 对字典按照value进行排序的方法
May 09 Python
python django中8000端口被占用的解决
Dec 17 Python
使用Python制作新型冠状病毒实时疫情图
Jan 28 Python
开启Django博客的RSS功能的实现方法
Feb 17 Python
面向新手解析python Beautiful Soup基本用法
Jul 11 Python
pycharm导入源码的具体步骤
Aug 04 Python
Python 高效编程技巧分享
Sep 10 Python
Pycharm安装python库的方法
Nov 24 Python
Django中如何用xlwt生成表格的方法步骤
Jan 31 Python
Python自动生产表情包
Mar 17 #Python
Python实现的异步代理爬虫及代理池
Mar 17 #Python
Python 专题一 函数的基础知识
Mar 16 #Python
python 专题九 Mysql数据库编程基础知识
Mar 16 #Python
Python实现树莓派WiFi断线自动重连的实例代码
Mar 16 #Python
Windows下安装python MySQLdb遇到的问题及解决方法
Mar 16 #Python
python Selenium爬取内容并存储至MySQL数据库的实现代码
Mar 16 #Python
You might like
PHP的SQL注入实现(测试代码安全不错)
2011/02/27 PHP
QQ互联一键登录审核不通过的解决方案
2014/09/10 PHP
PHP 开发者该知道的 5 个 Composer 小技巧
2016/02/03 PHP
PHP开发的微信现金红包功能示例
2017/06/29 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
Laravel框架模型的创建及模型对数据操作示例
2019/05/07 PHP
雄兵连第三季海报曝光,艾妮熙德成主角,蔷薇新造型
2021/03/09 国漫
javascript 数组的方法集合
2008/06/05 Javascript
通过javascript设置css属性的代码
2009/12/28 Javascript
jQuery.ajax 用户登录验证代码
2010/10/29 Javascript
js实现连个数字相加而不是拼接的方法
2014/02/23 Javascript
jQuery EasyUI datagrid实现本地分页的方法
2015/02/13 Javascript
JavaScript中setFullYear()方法的使用详解
2015/06/11 Javascript
JS Attribute属性操作详解
2016/05/19 Javascript
js获取元素的标签名实现方法
2016/10/08 Javascript
扩展jquery easyui tree的搜索树节点方法(推荐)
2016/10/28 Javascript
Javascript别踩白块儿(钢琴块儿)小游戏实现代码
2017/07/20 Javascript
JavaScript实现的搜索及高亮显示功能示例
2017/08/14 Javascript
深入理解Vue 的钩子函数
2018/09/05 Javascript
webpack4打包vue前端多页面项目
2018/09/17 Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
2019/06/10 jQuery
在Vue中用canvas实现二维码和图片合成海报的方法
2019/06/10 Javascript
5分钟教你用nodeJS手写一个mock数据服务器的方法
2019/09/10 NodeJs
[02:54]DOTA2英雄基础教程 暗影牧师戴泽
2013/12/05 DOTA
[03:41]2018完美盛典-《Fight With Us》
2018/12/16 DOTA
深入理解Python装饰器
2016/07/27 Python
使用Python-OpenCV消除图像中孤立的小区域操作
2020/07/05 Python
python实现AdaBoost算法的示例
2020/10/03 Python
美体小铺奥地利官方网站:The Body Shop奥地利
2019/04/11 全球购物
关于幼儿的自我评价
2013/12/18 职场文书
信息专业学生学习的自我评价
2014/02/17 职场文书
西湖英语导游词
2015/02/06 职场文书
欠条范文
2015/07/03 职场文书
手残删除python之后的补救方法
2021/06/26 Python
教你使用vscode 搭建react-native开发环境
2021/07/07 Javascript
mysql 联合索引生效的条件及索引失效的条件
2021/11/20 MySQL