- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章解决Django transaction进行事务管理踩过的坑由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Transaction是django进行数据库原子性操作在python层面上的实现.
简单来说, 被transaction.atomic()包裹的代码块只在代码块顺利完成后进行数据库层面的commit。实际开发当中,遇到了一些问题.
除非手动commit 。
transaction最基本的功能.
代码场景:
在事务当前启动celery异步任务, 无法获取未提交的改动.
1
2
3
4
5
6
7
8
|
def
example_view(request):
with transaction.atomic():
change_obj()
# 修改对象变量
obj.save()
async_task.delay(obj.
id
)
def
async_task(obj_id):
obj
=
Model.objects.get(pk
=
obj_id)
read_the_obj()
# 读取对象信息
|
在使用transaction当中, Model.save()都不做commit,因此如果在transaction当中设置异步任务,使用get()查询数据库,将看不到对象在事务当中的改变.这也是实现”可重复读”的事务隔离级别,即同一个事务里面的多次查询都应该保持结果不变.
不能理解为python操作的事务管理 。
代码如下:
1
2
3
4
5
6
7
8
|
def
example_view(request):
tag
=
False
with transaction.atomic():
tag
=
True
change_obj()
# 修改对象变量
obj.save()
raise
DataError
print
(
"tag = "
,tag)
|
1
|
tag
=
True
#输出内容
|
即使事务代码块发生了DataError,事务回滚,也仅是数据库层面的回滚,针对python的操作依然已完成.
甚至是对Model.Object进行的操作会也会存在变量当中.
如:
1
2
3
4
5
6
7
8
|
def
example_view(request):
obj.changed
=
False
with transaction.atomic():
obj.changed
=
True
change_obj()
# 修改对象其他变量
obj.save()
raise
DataError
print
(
"obj.changed = "
,obj.changed)
|
1
|
obj.changed
=
True
#输出内容
|
发生Dataerror异常的回滚仅在数据库层面操作,因此不可以根据model object的属性值判断是否正确完成了事务.
另外,虽然Django对数据库层面以ORM完成了很具体的抽象,但应该要清楚地意识到我们操作的model object和数据库内容本质不同,DJANGO只在查询和提交时进行数据库操作.
补充:Django 事务transaction.atomic()的使用方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
from
django.shortcuts
import
render
from
django.http
import
HttpResponse
from
django.views.generic
import
View
from
django.db
import
transaction
# 导入事务
# 类视图 (事务,@transaction.atomic装饰器)
class
MyView(View):
@transaction
.atomic
# transaction.atomic装饰器可以保证该函数中所有的数据库操作都在一个事务中。
def
post(
self
, request):
# 数据库操作1。。。
# 数据库操作2。。。
return
HttpResponse(
'ok'
)
# 类视图 (事务,保存点的使用)
class
MyView2(View):
@transaction
.atomic
def
post(
self
, request):
# 设置事务保存点
s1
=
transaction.savepoint()
# 可以设置多个保存点
# 数据库操作。。。
# 事务回滚 (如果发生异常,就回滚事务)
transaction.savepoint_rollback(s1)
# 可以回滚到指定的保存点
# 提交事务 (如果没有异常,就提交事务)
transaction.savepoint_commit(s1)
# 返回应答
return
HttpResponse(
'ok'
)
|
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我。如有错误或未考虑完全的地方,望不吝赐教.
原文链接:https://blog.csdn.net/m0_37422289/article/details/82221489 。
最后此篇关于解决Django transaction进行事务管理踩过的坑的文章就讲到这里了,如果你想了解更多关于解决Django transaction进行事务管理踩过的坑的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
前言 每日站会(Daily Standup)是团队统一节奏的、在固定时间发生的、帮助团队内部快速同步进展的敏捷实践活动: 站会的目的是让团队能更好地对齐 Sprint 目标;
jdbcTemplate 中的queryForList,你真的懂吗? 你想象中的queryForList是不是应该长成下面这种模样? String sql = "select *
python是一门清晰简洁的语言,如果你对一些细节不了解的话,就会掉入到那些深不见底的“坑”里,下面,我就来总结一些python里常见的坑。 列表创建和引用 嵌套列表的创建 使用*号来创建一个
如今,在DevOps当中建立安全体系显得比以往任何时候都更加重要。《2021年企业DevOps技能提升报告》指出,56%的受访者表示DevSecOps已经成为自动化工具中的一大必备要素。然而,D
前言 相信看到这个题目,可能大家都觉得是一个老生常谈的月经topic了。一直以来其实把握一个“值传递”基本上就能理解各种情况了,不过最近遇到了更深一点的“小坑”,与大家分享一下。 首先还是从最简
前言 Go 中的for range组合可以和方便的实现对一个数组或切片进行遍历,但是在某些情况下使用for range时很可能就会被"坑",下面用一段代码来模拟下:
大家好,我是明哥。 在开始之前,先考你一个非常 Go 味的经典问题:如何判断一个 interface{} 的值是否为 nil ? 这也是面试有可能会被问到的一个问题,这个问题很 “迷”,平时
ava并发包有很大一部分内容都是关于并发容器的,因此学习和搞懂这部分的内容很有必要。 Java 1.5 之前提供的同步容器虽然也能保证线程安全,但是性能很差,而 Java 1.5 版本之后提供的并发
大家好,我是煎鱼。 前几天在读者交流群里看到一位小伙伴,针对 interface 的使用有了比较大的疑惑。 无独有偶,我也在网上看到有小伙伴在 Go 面试的时候被问到了:
我是一名优秀的程序员,十分优秀!