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的加密模块md5、sha、crypt使用实例
Sep 28 Python
Python操作MySQL简单实现方法
Jan 26 Python
在Python的Django框架中编写编译函数
Jul 20 Python
python实现颜色空间转换程序(Tkinter)
Dec 31 Python
动感网页相册 python编写简单文件夹内图片浏览工具
Aug 17 Python
python对配置文件.ini进行增删改查操作的方法示例
Jul 28 Python
Python 使用指定的网卡发送HTTP请求的实例
Aug 21 Python
Python递归及尾递归优化操作实例分析
Feb 01 Python
python如何利用paramiko执行服务器命令
Nov 07 Python
Python urllib3软件包的使用说明
Nov 18 Python
使用Pytorch实现two-head(多输出)模型的操作
May 28 Python
Python实现列表拼接和去重的三种方式
Jul 02 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
用ODBC的分页显示
2006/10/09 PHP
PHP连接Access数据库的方法小结
2013/06/20 PHP
PHP实现获取客户端IP并获取IP信息
2015/03/17 PHP
CI框架常用方法小结
2016/05/17 PHP
php+ajax实现带进度条的上传图片功能【附demo源码下载】
2016/09/14 PHP
用svg制作富有动态的tooltip
2015/07/17 Javascript
JavaScript+html5 canvas绘制的小人效果
2016/01/27 Javascript
jQuery基于json与cookie实现购物车的方法
2016/04/15 Javascript
js添加事件的通用方法推荐
2016/05/15 Javascript
学习Angular中作用域需要注意的坑
2016/08/17 Javascript
jQuery实现ToolTip元素定位显示功能示例
2016/11/23 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
2016/12/27 Javascript
Angular2下使用pdf插件的方法详解
2017/04/29 Javascript
jQuery实现火车票买票城市选择切换功能
2017/09/15 jQuery
使用Vue动态生成form表单的实例代码
2018/04/26 Javascript
jQuery实现的简单歌词滚动功能示例
2019/01/07 jQuery
vue使用Font Awesome的方法步骤
2019/02/26 Javascript
小程序实现搜索框功能
2020/03/26 Javascript
vue实现直播间点赞飘心效果的示例代码
2019/09/20 Javascript
vue-router 路由传参用法实例分析
2020/03/06 Javascript
VueQuillEditor富文本上传图片(非base64)
2020/06/03 Javascript
python pdb调试方法分享
2014/01/21 Python
urllib2自定义opener详解
2014/02/07 Python
介绍Python中几个常用的类方法
2015/04/08 Python
Python中用于计算对数的log()方法
2015/05/15 Python
python实现汉诺塔递归算法经典案例
2021/03/01 Python
Python数据结构之单链表详解
2017/09/12 Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
2019/02/26 Python
Pandas实现一列数据分隔为两列
2020/05/18 Python
Python如何优雅删除字符列表空字符及None元素
2020/06/25 Python
canvas三角函数模拟水波效果的示例代码
2018/07/03 HTML / CSS
英国领先的高级美容和在线皮肤诊所:Face the Future
2020/06/17 全球购物
mysql有关权限的表都有哪几个
2015/04/22 面试题
2015年业务员工作总结范文
2015/04/07 职场文书
餐饮行业关注的9大营销策略
2019/08/26 职场文书