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接收多播数据的代码
Mar 01 Python
Python内置函数Type()函数一个有趣的用法
Feb 18 Python
Python实现获取操作系统版本信息方法
Apr 08 Python
深入解析Python中的WSGI接口
May 11 Python
请不要重复犯我在学习Python和Linux系统上的错误
Dec 12 Python
对numpy中数组元素的统一赋值实例
Apr 04 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
Apr 08 Python
python3基于OpenCV实现证件照背景替换
Jul 18 Python
python的依赖管理的实现
May 14 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
Jun 11 Python
python向图片里添加文字
Nov 26 Python
python -v 报错问题的解决方法
Sep 15 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
Search Engine Friendly的URL设计
2006/10/09 PHP
浅析ThinkPHP中的pathinfo模式和URL重写
2014/01/06 PHP
php阳历转农历优化版
2016/08/08 PHP
php原生导出excel文件的两种方法(推荐)
2016/11/19 PHP
php基于SQLite实现的分页功能示例
2017/06/21 PHP
javascript权威指南 学习笔记之null和undefined
2011/09/25 Javascript
JS截取字符串常用方法详细整理
2013/10/28 Javascript
transport.js和jquery冲突问题的解决方法
2015/02/10 Javascript
JavaScript实现级联菜单的方法
2015/06/29 Javascript
jquery实现树形菜单完整代码
2015/12/29 Javascript
快速使用Bootstrap搭建传送带
2016/05/06 Javascript
javaScript中定义类或对象的五种方式总结
2016/12/04 Javascript
微信小程序之获取当前位置经纬度以及地图显示详解
2017/05/09 Javascript
AngularJS使用ng-class动态增减class样式的方法示例
2017/05/18 Javascript
JQuery 选择器、DOM节点操作练习实例
2017/09/28 jQuery
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
AngularJs 禁止模板缓存的方法
2017/11/28 Javascript
快速解决vue-cli不能初始化webpack模板的问题
2018/03/20 Javascript
Vue子组件向父组件通信与父组件调用子组件中的方法
2018/06/22 Javascript
小程序实现单选多选功能
2018/11/04 Javascript
Vue 实现前端权限控制的示例代码
2019/07/09 Javascript
[02:44]DOTA2英雄基础教程 魅惑魔女
2014/01/07 DOTA
python实现自动重启本程序的方法
2015/07/09 Python
Python操作Redis之设置key的过期时间实例代码
2018/01/25 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
anaconda如何查看并管理python环境
2019/07/05 Python
Django操作session 的方法
2020/03/09 Python
美赞臣营养马来西亚旗舰店:Enfagrow马来西亚
2019/07/26 全球购物
Dodax奥地利:音乐、电影、书籍、玩具、电子产品等
2019/08/31 全球购物
SQL中where和having的区别
2012/06/17 面试题
高中军训感言1000字
2014/03/01 职场文书
科长竞聘演讲稿
2014/05/16 职场文书
解除劳动合同协议书范本2014
2014/09/25 职场文书
2014年服务员个人工作总结
2014/12/23 职场文书
Golang日志包的使用
2022/04/20 Golang
MySQL索引失效场景及解决方案
2022/07/23 MySQL