mysql django

实践:

django @transaction.atomic 机制分析
 
 1、数据库清空表Tab
 2、请求django-view
    
    @transaction.atomic(using=settings.TRANSACTION_DEFAULT_USING)
    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        
        
        i = Tab.objects.all()
        print(i[0])
        raise False
    
    
    '''
    控制台输出
    (0.003) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.003) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None

    '''
    结果可以打印一条db数据
 3、最终数据库表仍为空

猜想:
 在session中,设置隔离级别为“读提交的”,注意,这里的“提交的”是指其他会话“提交的”,而该会话本身的“未提交”的是在该会话中可以读到的;

@transaction.atomic(using=settings.TRANSACTION_DEFAULT_USING)

def atomic(using=None, savepoint=True):
# Bare decorator: @atomic -- although the first argument is called
# `using`, it's actually the function being decorated.
if callable(using):
return Atomic(DEFAULT_DB_ALIAS, savepoint)(using)
# Decorator: @atomic(...) or context manager: with atomic(...): ...
else:
return Atomic(using, savepoint)


#################################
# Decorators / context managers #
#################################

class Atomic(ContextDecorator):
"""
Guarantee the atomic execution of a given block.

An instance can be used either as a decorator or as a context manager.

When it's used as a decorator, __call__ wraps the execution of the
decorated function in the instance itself, used as a context manager.

When it's used as a context manager, __enter__ creates a transaction or a
savepoint, depending on whether a transaction is already in progress, and
__exit__ commits the transaction or releases the savepoint on normal exit,
and rolls back the transaction or to the savepoint on exceptions.

It's possible to disable the creation of savepoints if the goal is to
ensure that some code runs within a transaction without creating overhead.

A stack of savepoints identifiers is maintained as an attribute of the
connection. None denotes the absence of a savepoint.

This allows reentrancy even if the same AtomicWrapper is reused. For
example, it's possible to define `oa = atomic('other')` and use `@oa` or
`with oa:` multiple times.

Since database connections are thread-local, this is thread-safe.

This is a private API.
"""

def __init__(self, using, savepoint):
self.using = using
self.savepoint = savepoint

def __enter__(self):
connection = get_connection(self.using)

if not connection.in_atomic_block:
# Reset state when entering an outermost atomic block.
connection.commit_on_exit = True
connection.needs_rollback = False
if not connection.get_autocommit():
# sqlite3 in Python < 3.6 doesn't handle transactions and
# savepoints properly when autocommit is off.
# Turning autocommit back on isn't an option; it would trigger
# a premature commit. Give up if that happens.
if connection.features.autocommits_when_autocommit_is_off:
raise TransactionManagementError(
"Your database backend doesn't behave properly when "
"autocommit is off. Turn it on before using 'atomic'.")
# Pretend we're already in an atomic block to bypass the code
# that disables autocommit to enter a transaction, and make a
# note to deal with this case in __exit__.
connection.in_atomic_block = True
connection.commit_on_exit = False

if connection.in_atomic_block:
# We're already in a transaction; create a savepoint, unless we
# were told not to or we're already waiting for a rollback. The
# second condition avoids creating useless savepoints and prevents
# overwriting needs_rollback until the rollback is performed.
if self.savepoint and not connection.needs_rollback:
sid = connection.savepoint()
connection.savepoint_ids.append(sid)
else:
connection.savepoint_ids.append(None)
else:
connection.set_autocommit(False, force_begin_transaction_with_broken_autocommit=True)
connection.in_atomic_block = True

def __exit__(self, exc_type, exc_value, traceback):
connection = get_connection(self.using)

if connection.savepoint_ids:
sid = connection.savepoint_ids.pop()
else:
# Prematurely unset this flag to allow using commit or rollback.
connection.in_atomic_block = False

try:
if connection.closed_in_transaction:
# The database will perform a rollback by itself.
# Wait until we exit the outermost block.
pass

elif exc_type is None and not connection.needs_rollback:
if connection.in_atomic_block:
# Release savepoint if there is one
if sid is not None:
try:
connection.savepoint_commit(sid)
except DatabaseError:
try:
connection.savepoint_rollback(sid)
# The savepoint won't be reused. Release it to
# minimize overhead for the database server.
connection.savepoint_commit(sid)
except Error:
# If rolling back to a savepoint fails, mark for
# rollback at a higher level and avoid shadowing
# the original exception.
connection.needs_rollback = True
raise
else:
# Commit transaction
try:
connection.commit()
except DatabaseError:
try:
connection.rollback()
except Error:
# An error during rollback means that something
# went wrong with the connection. Drop it.
connection.close()
raise
else:
# This flag will be set to True again if there isn't a savepoint
# allowing to perform the rollback at this level.
connection.needs_rollback = False
if connection.in_atomic_block:
# Roll back to savepoint if there is one, mark for rollback
# otherwise.
if sid is None:
connection.needs_rollback = True
else:
try:
connection.savepoint_rollback(sid)
# The savepoint won't be reused. Release it to
# minimize overhead for the database server.
connection.savepoint_commit(sid)
except Error:
# If rolling back to a savepoint fails, mark for
# rollback at a higher level and avoid shadowing
# the original exception.
connection.needs_rollback = True
else:
# Roll back transaction
try:
connection.rollback()
except Error:
# An error during rollback means that something
# went wrong with the connection. Drop it.
connection.close()

finally:
# Outermost block exit when autocommit was enabled.
if not connection.in_atomic_block:
if connection.closed_in_transaction:
connection.connection = None
else:
connection.set_autocommit(True)
# Outermost block exit when autocommit was disabled.
elif not connection.savepoint_ids and not connection.commit_on_exit:
if connection.closed_in_transaction:
connection.connection = None
else:
connection.in_atomic_block = False

def atomic(using=None, savepoint=True):
# Bare decorator: @atomic -- although the first argument is called
# `using`, it's actually the function being decorated.
if callable(using):
return Atomic(DEFAULT_DB_ALIAS, savepoint)(using)
# Decorator: @atomic(...) or context manager: with atomic(...): ...
else:
return Atomic(using, savepoint)



def atomic(using=None, savepoint=True):
# Bare decorator: @atomic -- although the first argument is called
# `using`, it's actually the function being decorated.
if callable(using):
return Atomic(DEFAULT_DB_ALIAS, savepoint)(using)
# Decorator: @atomic(...) or context manager: with atomic(...): ...
else:
return Atomic(using, savepoint)

Database transactions | Django documentation | Django https://docs.djangoproject.com/en/3.0/topics/db/transactions/
atomic blocks can be nested. In this case, when an inner block completes successfully, its effects can still be rolled back if an exception is raised in the outer block at a later point.

回滚原理 Since database connections are thread-local, this is thread-safe.的更多相关文章

  1. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  2. ssh事务回滚,纪念这几个月困扰已久的心酸

    以前的事务采用的是JTA,xml注入的方式.本人就着开发要优雅合理利用轮子的态度,一直不满意JTA式的申明和切入方式. spring的注解方式多优雅,可是万恶的直到项目快要上线时终于找到了注解式不能回 ...

  3. Jenkins:参数化构建:分支|模块|回滚|打印日志

    @ 目录 多分支 安装Git Parameter Plug-In 配置参数 选择构建分支 分模块 前提 分模块build 参数配置 分模块shell脚本 mvn 的基本用法 分模块运行 Jenkins ...

  4. Java Thread Local – How to use and code sample(转)

    转载自:https://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/ Thread Local ...

  5. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

  6. Oracle-11g-R2(11.2.0.3.x)RAC Oracle Grid & Database 零宕机方式回滚 PSU(自动模式)

    回滚环境: 1.源库版本: Grid Infrastructure:11.2.0.3.15 Database:11.2.0.3.15 2.目标库版本: Grid Infrastructure:11.2 ...

  7. 难道你还不知道Spring之事务的回滚和提交的原理吗,这篇文章带你走进源码级别的解读。

    上一篇文章讲解了获取事务,并通过获取的connection设置只读,隔离级别等:这篇文章讲事务剩下的回滚和提交. 事务的回滚处理 之前已经完成了目标方法运行前的事务准备工作.而这些准备工作的最大目的无 ...

  8. C#中回滚TransactionScope的使用方法和原理

    TransactionScope只要一个操作失败,它会自动回滚,Complete表示事务完成   实事上,一个错误的理解就是Complete()方法是提交事务的,这是错误的,事实上,它的作用的表示本事 ...

  9. 【转载】C#中回滚TransactionScope的使用方法和原理

    TransactionScope只要一个操作失败,它会自动回滚,Complete表示事务完成 实事上,一个错误的理解就是Complete()方法是提交事务的,这是错误的,事实上,它的作用的表示本事务完 ...

随机推荐

  1. Blogs禁止页面选中复制功能

    说明:只需要在博客侧边栏公告(支持HTML代码) (支持 JS 代码)里面添加如下代码 /* 在页面定制 CSS 代码处添加如下样式 */ html,body{ moz-user-select: -m ...

  2. CVE-2017-10271漏洞复现

    漏洞描述 Weblogic的WLS Security组件对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令. ...

  3. 【Java并发编程】阿里最喜欢问的几道线程池的面试题?

    引言 上一篇文章我们有介绍过线程池的一个基本执行流程<[Java并发编程]面试必备之线程池>以及它的7个核心参数,以及每个参数的作用.以及如何去使用线程池 还留了几个小问题..建议看这篇文 ...

  4. Oracle RedoLog-基本概念和组成

    Oracle 数据库恢复操作最关键的依据就是 redo log,它记录了对数据库所有的更改操作.在研究如何提取 redolog 中 DML 操作的过程可谓一波三折,因为介绍 redolog 结构细节的 ...

  5. SpringBoot官网提供所有组件整理

    下面所有SpringBoot组件整理来自于:https://start.spring.io/,紧随Spring社区的步伐...... Developer Tools Spring Boot DevTo ...

  6. git基础-git别名

    Git 并不会在你输入部分命令时自动推断出你想要的命令. 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名. 这里有一些例子你可以试试: $ ...

  7. spark的thriftservr的高可用

    triftserver是基于jdbc的一个spark的服务,可以做web查询,多客户端访问,但是thriftserver没有高可用,服务挂掉后就无法在访问,所有使用注册到zk的方式来实现高可用 一.版 ...

  8. U盘使用技巧篇 制作一般人删除不了的文件(宣传视频) (量产开卡)

    一. 视频制作成ISO ,放好 视频  图标文件 制作工具 : UltraISO 图标制作: 插入光盘状态:用autorun.inf格式:[autorun]open=Install.exe 点击光盘时 ...

  9. 解决黑群晖"抱歉,您所指定的页面不存在"-记一次黑群晖修复案例

    起因 搞了一个usb外接硬盘准备备份数,刚好看到群晖有个工具软件"USB Copy". 安装后设置拷贝docker文件夹,然后就悲剧了,nas主页抛出提示 一开始也是直接网上搜索标 ...

  10. Centos 6 下安装 OSSEC-2.8.1 (一)

    ossec -2.8.1 安装: ## 1 ) 安装依赖包: RedHat / Centos / Fedora / Amazon Linux yum install -y pcre mysql mys ...