大兴快速网站建设哪家好在线培训考试系统
下面是小凰凰的简介,看下吧!
💗人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活
💗学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习中)
💗您的点赞、收藏、关注是对博主创作的最大鼓励,在此谢过!
有相关技能问题可以写在下方评论区,我们一起学习,一起进步。
后期会不断更新python全栈学习笔记,秉着质量博文为原则,写好每一篇博文。
文章目录
- 一、锁(了解)
- 二、事务
- 1、全局开启(不推荐)
- 2、局部使用事务(推荐)
- (1)给函数做装饰器来使用
- (2)作为上下文管理器来使用,其实就是设置事务的保存点
看本篇博文之前需要对mysql锁与事务非常熟悉,
点我学习:mysql锁机制
点我学习:mysql事务
一、锁(了解)
行级锁
select_for_update(nowait=False, skip_locked=False) #注意必须用在事务里面,至于如何开启事务,我们看下面的事务一节。
返回一个锁住行直到事务结束的查询集,如果数据库支持,它将生成一个 SELECT … FOR UPDATE 语句。
举个例子:
entries = Entry.objects.select_for_update().filter(author=request.user) #加互斥锁,由于mysql在查询时自动加的是共享锁,所以我们可以手动加上互斥锁。create、update、delete操作时,mysql自动加行级互斥锁
所有匹配的行将被锁定,直到事务结束。这意味着可以通过锁防止数据被其它事务修改。
一般情况下如果其他事务锁定了相关行,那么本查询将被阻塞,直到锁被释放。 如果这不想要使查询阻塞的话,使用select_for_update(nowait=True)。 如果其它事务持有冲突的锁,互斥锁, 那么查询将引发 DatabaseError 异常。你也可以使用select_for_update(skip_locked=True)忽略锁定的行。 nowait和 skip_locked是互斥的,同时设置会导致ValueError。
目前,postgresql,oracle和mysql数据库后端支持select_for_update()。 但是,MySQL不支持nowait和skip_locked参数。
使用不支持这些选项的数据库后端(如MySQL)将nowait=True或skip_locked=True转换为select_for_update()将导致抛出DatabaseError异常,这可以防止代码意外终止。
二、事务
关于MySQL的事务处理,我上面的mysql博客已经说的很清楚了,那么我们来看看Django是如果做事务处理的。django1.8版本之前是有很多种添加事务的方式的,中间件的形式(全局的)、函数装饰器的形式,上下文管理器的形式等,但是很多方法都在1.8版之后给更新了,下面我们只说最新的三种方式:
1、全局开启(不推荐)
在Web应用中,常用的事务处理方式是将每个请求都包裹在一个事务中。这个功能使用起来非常简单,你只需要将它的配置项ATOMIC_REQUESTS设置为True。
它是这样工作的:当有请求过来时,Django会在调用视图方法前开启一个事务。如果请求却正确处理并正确返回了结果,Django就会提交该事务。否则,Django会回滚该事务。
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'mxshop','HOST': '127.0.0.1','PORT': '3306','USER': 'root','PASSWORD': '123','OPTIONS': {"init_command": "SET default_storage_engine='INNODB'",#'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", #配置开启严格sql模式}"ATOMIC_REQUESTS": True, #全局开启事务,绑定的是http请求响应整个过程"AUTOCOMMIT":False, #全局取消自动提交,慎用},'other':{'ENGINE': 'django.db.backends.mysql', ......} #还可以配置其他数据库
}
上面这种方式是统一个http请求对应的所有sql都放在一个事务中执行
(要么这个http请求成功,要么这个http请求失败,对数据库不产生任何影响)。
2、局部使用事务(推荐)
(1)给函数做装饰器来使用
from django.db import transaction@transaction.atomic
def viewfunc(request):# This code executes inside a transaction.do_stuff()
整个视图函数为一个事务!
(2)作为上下文管理器来使用,其实就是设置事务的保存点
from django.db import transactiondef viewfunc(request):with transaction.atomic(): # 保存点# This code executes inside a transaction.do_more_stuff()
with transaction.atomic()下的缩进部分为一个事务!