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通过字典dict判断指定键值是否存在的方法
Mar 21 Python
python创建列表并给列表赋初始值的方法
Jul 28 Python
Python socket网络编程TCP/IP服务器与客户端通信
Jan 05 Python
django实现同一个ip十分钟内只能注册一次的实例
Nov 03 Python
Python找出最小的K个数实例代码
Jan 04 Python
python迭代dict的key和value的方法
Jul 06 Python
python3的数据类型及数据类型转换实例详解
Aug 20 Python
部署Django到阿里云服务器教程示例
Jun 03 Python
python文件读取失败怎么处理
Jun 23 Python
Python中openpyxl实现vlookup函数的实例
Oct 28 Python
去除python中的字符串空格的简单方法
Dec 22 Python
Python异常类型以及处理方法汇总
Jun 05 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
自动分页的不完整解决方案
2007/01/12 PHP
PHP判断图片格式的七种方法小结
2013/06/03 PHP
thinkphp获取栏目和文章当前位置的方法
2014/10/29 PHP
PHP图像处理 imagestring添加图片水印与文字水印操作示例
2020/02/06 PHP
新闻内页-JS分页
2006/06/07 Javascript
javascript string字符串优化问题
2011/07/31 Javascript
javascript事件函数中获得事件源的两种不错方法
2014/03/17 Javascript
Js获取图片原始宽高的实现代码
2016/05/17 Javascript
JavaScript实现时间倒计时跳转(推荐)
2016/06/28 Javascript
Javascript中数组去重与拍平的方法示例
2017/02/03 Javascript
webpack2.0搭建前端项目的教程详解
2017/04/05 Javascript
JS动态添加的div点击跳转到另一页面实现代码
2017/09/30 Javascript
详解webpack编译多页面vue项目的配置问题
2017/12/11 Javascript
js变量声明var使用与不使用的区别详解
2019/01/21 Javascript
原生js添加一个或多个类名的方法分析
2019/07/30 Javascript
Bootstrap实现前端登录页面带验证码功能完整示例
2020/03/26 Javascript
[56:18]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#2 MVP.Phx VS Fnatic第二局
2016/03/05 DOTA
使用Python的Twisted框架编写简单的网络客户端
2015/04/16 Python
python实现批量修改图片格式和尺寸
2018/06/07 Python
python3实现磁盘空间监控
2018/06/21 Python
python将控制台输出保存至文件的方法
2019/01/07 Python
Python交互环境下打印和输入函数的实例内容
2020/02/16 Python
安装pyecharts1.8.0版本后导入pyecharts模块绘图时报错: “所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置 ”的解决方法
2020/08/18 Python
如何快速一次性卸载所有python包(第三方库)呢
2020/10/20 Python
python 读取串口数据的示例
2020/11/09 Python
python 如何对logging日志封装
2020/12/02 Python
加拿大女装网上购物:Reitmans
2016/10/20 全球购物
迪拜航空官方网站:flydubai
2017/04/20 全球购物
专注澳大利亚特产和新西兰特产的澳洲中文网:0061澳洲制造
2019/03/24 全球购物
JAVA中运算符的分类及举例
2015/09/12 面试题
设置器与访问器的定义以及各自特点
2016/01/08 面试题
酒店工作职员求职简历的自我评价
2013/10/23 职场文书
文明寄语大全
2014/04/11 职场文书
工程竣工验收申请报告
2015/05/15 职场文书
毕业证明书
2015/06/19 职场文书
详解vue身份认证管理和租户管理
2021/05/25 Vue.js