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之永远强大的函数
Sep 14 Python
使用Python的Scrapy框架编写web爬虫的简单示例
Apr 17 Python
Python操作列表之List.insert()方法的使用
May 20 Python
浅谈python迭代器
Nov 08 Python
Python处理命令行参数模块optpars用法实例分析
May 31 Python
Python中函数参数调用方式分析
Aug 09 Python
python中下标和切片的使用方法解析
Aug 27 Python
500行代码使用python写个微信小游戏飞机大战游戏
Oct 16 Python
python3 使用openpyxl将mysql数据写入xlsx的操作
May 15 Python
keras 读取多标签图像数据方式
Jun 12 Python
Python基于pillow库实现生成图片水印
Sep 14 Python
selenium学习教程之定位以及切换frame(iframe)
Jan 04 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异常处理技术,顶级异常处理器
2012/06/13 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
js 模拟实现类似c#下的hashtable的简单功能代码
2010/01/24 Javascript
基于jquery的3d效果实现代码
2011/03/23 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
jquery中的on方法使用介绍
2013/12/29 Javascript
Javascript中的arguments与重载介绍
2015/03/15 Javascript
JavaScript简单表格编辑功能实现方法
2015/04/16 Javascript
jQuery控制文本框只能输入数字和字母及使用方法
2016/05/26 Javascript
AngularJS入门教程之Helloworld示例
2016/12/25 Javascript
boostrapTable的refresh和refreshOptions区别浅析
2017/01/22 Javascript
浅谈jQuery中事情的动态绑定
2017/02/12 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
手机端转换rem适应
2017/04/01 Javascript
jQuery实现鼠标响应式淘宝动画效果示例
2018/02/13 jQuery
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
jQuery实现轮播图及其原理详解
2020/04/12 jQuery
vue+echarts实现动态绘制图表及异步加载数据的方法
2018/10/17 Javascript
解决vue中的无限循环问题
2020/07/27 Javascript
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
[14:50]2018DOTA2亚洲邀请赛开幕式
2018/04/03 DOTA
用实例分析Python中method的参数传递过程
2015/04/02 Python
Python探索之URL Dispatcher实例详解
2017/10/28 Python
Python实现一个服务器监听多个客户端请求
2018/04/12 Python
python生成n个元素的全组合方法
2018/11/13 Python
对python3 中方法各种参数和返回值详解
2018/12/15 Python
python实现维吉尼亚加密法
2019/03/20 Python
Python request操作步骤及代码实例
2020/04/13 Python
关于VPN
2012/06/10 面试题
建议书怎么写
2014/03/12 职场文书
小学生作文评语集锦
2014/12/25 职场文书
2015年消防工作总结
2015/04/24 职场文书
汉字听写大会观后感
2015/06/12 职场文书
MySQL中distinct与group by之间的性能进行比较
2021/05/26 MySQL
Python实现信息轰炸工具(再也不怕说不过别人了)
2021/06/11 Python
Android开发实现极为简单的QQ登录页面
2022/04/24 Java/Android