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的Twisted框架编写简单的网络客户端
Apr 16 Python
python搜索指定目录的方法
Apr 29 Python
Python的Django框架中的数据过滤功能
Jul 17 Python
Django Highcharts制作图表
Aug 27 Python
Python环境搭建之OpenCV的步骤方法
Oct 20 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
May 16 Python
利用Python查看微信共同好友功能的实现代码
Apr 24 Python
深入浅析Python中的迭代器
Jun 04 Python
如何关掉pycharm中的python console(图解)
Oct 31 Python
pytorch中获取模型input/output shape实例
Dec 30 Python
Python如何重新加载模块
Jul 29 Python
selenium自动化测试入门实战
Dec 21 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多个文件上传到服务器实例
2014/10/29 PHP
PHP实现WebService的简单示例和实现步骤
2015/03/27 PHP
php利用递归实现删除文件目录的方法
2016/09/23 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
PHP实现找出有序数组中绝对值最小的数算法分析
2017/08/07 PHP
PHP Include文件实例讲解
2019/02/15 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
prototype 的说明 js类
2006/09/07 Javascript
SyntaxHighlighter代码加色使用方法
2008/09/07 Javascript
Extjs 几个方法的讨论
2010/01/28 Javascript
js focus不起作用的解决方法(主要是因为dom元素是否加载完成)
2010/11/05 Javascript
Javacript实现颜色梯度变化和渐变的效果代码
2013/05/31 Javascript
js调试系列 断点与动态调试[基础篇]
2014/06/18 Javascript
jQuery超赞的评分插件(8款)
2015/08/20 Javascript
详解前端构建工具gulpjs的使用介绍及技巧
2017/01/19 Javascript
js实现3D图片展示效果
2017/03/09 Javascript
JavaScript 程序错误Cannot use 'in' operator to search的解决方法
2017/07/10 Javascript
简单实现jQuery轮播效果
2017/08/18 jQuery
详解Vue.js 作用域、slot用法(单个slot、具名slot)
2019/10/15 Javascript
python实现根据ip地址反向查找主机名称的方法
2015/04/29 Python
Python使用cx_Oracle模块将oracle中数据导出到csv文件的方法
2015/05/16 Python
python3结合openpyxl库实现excel操作的实例代码
2018/09/11 Python
selenium+python 对输入框的输入处理方法
2018/10/11 Python
python 运用Django 开发后台接口的实例
2018/12/11 Python
Python生成器的使用方法和示例代码
2019/03/04 Python
Django框架模板的使用方法示例
2019/05/25 Python
python实现从本地摄像头和网络摄像头截取图片功能
2019/07/11 Python
PyCharm中配置PySide2的图文教程
2020/06/18 Python
详解移动端Html5页面中1px边框的几种解决方法
2018/07/24 HTML / CSS
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
毕业设计论文致谢词
2015/05/14 职场文书
业务员管理制度范本
2015/08/06 职场文书
导游词之藏龙百瀑景区
2019/12/30 职场文书
如何用RabbitMQ和Swoole实现一个异步任务系统
2021/05/29 PHP
使用php的mail()函数实现发送邮件功能
2021/06/03 PHP
mysql脏页是什么
2021/07/26 MySQL