django 中的事务和锁
django 中的事务和锁
锁
在sql 中,大致分为以下三种锁
- 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
在sql 中,当我们进行修改某一条记录,它会自动进行加锁,查询数据的时候,加锁为共享锁,别人不能修改但是可以进行查看,修改数据时候,加的是排它锁,别人既不能查看也不能修改
共享锁 S:不能修改 SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE 排它锁 X:不能查改 SELECT * FROM table_name WHERE ... FOR UPDATE
综上,其实对sql 来说,基本已经可以满足我们的要求,但是如果说,我们的要求是当我们一条记录在被查看时,别人也不能查看呢?
虽然看起来确实很奇怪,但是类似的要求是有的,对于sql 语句,可以用上面的方法来加锁,在ORM里那么,我们就可以这么做:
# 额外增加排它锁 entries = models.Book.objects.select_for_update().filter(price='25')
django 可以增加表锁,这里略过
事务
事务是恢复和并发控制的基本单位。
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
一系列查询只有全部正确才会正确执行,一条出错全部不执行
sql 开启事务
start transaction 或者 begin
设置方法
1.全局配置:setting.py中
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 需要自己创建的库,在mysql中需要已经存在djangoStudy的库 'NAME': 'djangoStudy', 'USER':'root', 'PASSWORD':'SLQ1213852138000', 'HOST':'127.0.0.1', 'PORT':'3306', 'ATOMIC_REQUESTS':True, # 全局开启事务 } }
它会把一个http请求的全部sql 都打包成一个事务,一个失败则全都失败,如果想要单独取消掉,view中应该这么写:
from django.db import transaction # 取消事务 @transaction.non_atomic_requests def testLock(request): pass @transaction._non_atomic_requests(using='other') def testLock2(request): pass
2.局部加事务
a.装饰器增加
from django.db import transaction @transaction.atomic def testLock3(): pass
b.上下文管理器增加
from django.db import transaction def testLock4(): with transaction.atomic(): # 一个方法逻辑 pass
大三党,大家有问题可以多多建议
浙公网安备 33010602011771号