ORM-事务和锁
一、事务
事务四大特点:原子性、一致性、隔离性、排它性
Django中添加事务的方式主要有下列几种,中间件形式(全局的)、装饰器的形式、上下文管理器形式。
1.全局开启
在Web应用中,常用的事务处理方式是将每个请求都包裹在一个事务中。只需要将它的配置项ATOMIC_REQUESTS设置为True即可。
当有请求过来时,Django会在调用视图方法前开启一个事务。如果请求却正确处理并正确返回了结果,Django就会提交该事务。否则,Django会回滚该(rollback)事务。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'orm_database',
'USER': 'root',
'PASSWORD': 'mkc930224',
'HOST': '127.0.0.1',
'port': 3306,
'ATOMIC_REQUESTS': True
}
'others':{
pass
}
}
如果要对某个http请求开后门(然后自定义事务),可以用non_atomic_requests修饰器,那么他就不受事务的管控了。
但是Django 文档中说,不推荐这么做。因为如果将事务跟 HTTP 请求绑定到一起的时,然而view 是依赖于应用程序对数据库的查询语句效率和数据库当前的锁竞争情况。当流量上来的时候,性能会有影响。
from django.db import transaction
@transaction.non_atomic_requests
def my_view(request):
do_stuff()
#other为其他的数据库,可以在settings中配置
@transaction.non_atomic_requests(using='other')
def my_other_view(request):
do_stuff_on_the_other_database()
2.装饰器形式
.atomic允许我们在执行代码块时,在数据库层面提供原子性保证。 如果代码块成功完成, 相应的变化会被提交到数据库进行commit;如果执行期间遇到异常,则会将该段代码所涉及的所有更改回滚。
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()
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)
以上是atomic的源码,using=None表示使用什么数据库,savepoint是开启事务保存点
3.上下文管理器形式
本质上就是设置事务的保存点。出现完整性错误的处理可以放在try/except中,即将with transaction.atomic()放在try中
from django.db import transaction
def viewfunc(request):
# This code executes in autocommit mode (Django's default).
do_stuff()
with transaction.atomic(): #保存点
# This code executes inside a transaction.
do_more_stuff()
do_other_stuff()
二、锁
共享锁、互斥锁/排它锁、行级锁、表锁。
mysql在查询时自动加的是共享锁,我们可以手动加上互斥锁。在create、update、delete操作时,mysql自动加行级互斥锁。
目前,postgresql,oracle和mysql数据库后端支持select_for_update()。 但是,MySQL不支持nowait和skip_locked参数。