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 相关文章推荐
django框架如何集成celery进行开发
May 24 Python
django 发送手机验证码的示例代码
Apr 25 Python
用python写扫雷游戏实例代码分享
May 27 Python
解决Python找不到ssl模块问题 No module named _ssl的方法
Apr 29 Python
Python3实现mysql连接和数据框的形成(实例代码)
Jan 17 Python
基于Tensorflow批量数据的输入实现方式
Feb 05 Python
python 非线性规划方式(scipy.optimize.minimize)
Feb 11 Python
在Python IDLE 下调用anaconda中的库教程
Mar 09 Python
如何学习Python time模块
Jun 03 Python
学python爬虫能做什么
Jul 29 Python
用python写PDF转换器的实现
Oct 29 Python
python 写一个文件分发小程序
Dec 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
PHP+MySQL5.0中文乱码解决方法
2006/11/20 PHP
兼容性比较好的PHP生成缩略图的代码
2011/01/12 PHP
PHP企业级应用之常见缓存技术篇
2011/01/27 PHP
浅析php工厂模式
2014/11/25 PHP
PHP+MySQL实现无极限分类栏目的方法
2015/12/23 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
List Information About the Binary Files Used by an Application
2007/06/11 Javascript
javascript 操作select下拉列表框的一点小经验
2010/03/20 Javascript
js实现倒计时时钟的示例代码
2013/12/17 Javascript
解决jquery中美元符号命名冲突问题
2014/01/08 Javascript
jquery实现的图片点击滚动效果
2014/04/29 Javascript
Windows系统下Node.js的简单入门教程
2015/06/23 Javascript
Bootstrap复选框和单选按钮美化插件(推荐)
2016/11/23 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
详解Vue.js组件可复用性的混合(mixin)方式和自定义指令
2017/09/06 Javascript
layui中使用jquery控制radio选中事件的示例代码
2018/08/15 jQuery
JavaScript实现消消乐的源代码
2021/01/12 Javascript
python实现的生成随机迷宫算法核心代码分享(含游戏完整代码)
2014/07/11 Python
python 使用get_argument获取url query参数
2017/04/28 Python
Python实现微信自动好友验证,自动回复,发送群聊链接方法
2019/02/21 Python
Python 实例方法、类方法、静态方法的区别与作用
2019/08/14 Python
python定间隔取点(np.linspace)的实现
2019/11/27 Python
python实现快速文件格式批量转换的方法
2020/10/16 Python
python利用pytesseract 实现本地识别图片文字
2020/12/14 Python
Html5 Canvas动画基础碰撞检测的实现
2018/12/06 HTML / CSS
OPPO手机官方商城:中国手机市场出货量第一品牌
2017/10/18 全球购物
飞利信loadrunner和软件测试笔试题
2012/09/22 面试题
银行委托书范本
2014/04/04 职场文书
小学三年级学生评语
2014/04/22 职场文书
预备党员思想汇报1000字
2014/10/07 职场文书
2015年三万活动总结
2015/03/25 职场文书
傅雷家书读书笔记
2015/06/29 职场文书
学生会任命书范本
2015/09/21 职场文书
解读Vue组件注册方式
2021/05/15 Vue.js
MySql 8.0及对应驱动包匹配的注意点说明
2021/06/23 MySQL
opencv-python图像配准(匹配和叠加)的实现
2021/06/23 Python