在进行后端业务开始操作修改数据库时,可能会涉及到多张表的数据修改,对这些数据的修改应该是一个整体事务,即要么一起成功,要么一起失败,Django中对于数据库的事务,默认每执行一句数据库操作,便会自动提交。我们需要在保存数据库操作中自己控制数据库事务的执行流程
在Django中可以通过django.db.transaction模块提供的atomic来定义一个事务,atomic提供两种用法:
- 装饰器的用法(在这个函数下如果报错,那么这个函数中所有sql语句都会撤销):
from django.db import transaction
@transaction.atomic
def clear_over_stock():
"""
清除过期任务库存
:return:
"""
- with用法(创建保存点和回滚到保存点的sql将会被撤销):
from django.db import transaction
def viewfunc(request):
# 这部分代码不在事务中,会被Django自动提交
...
with transaction.atomic():
# 这部分代码会在事务中执行
...
- 在事务中的一些操作
# 创建保存点
save_id = transaction.savepoint()
......
# 回滚到保存点()
transaction.savepoint_rollback(save_id)
......
# 主动提交(相当于 对象.save())
transaction.savepoint_commit(save_id)
# 清除保存点
transaction.clean_savepoints() #清除保存点
- 但是要注意一点,django中,开启事务之后,里面一定不能用try except去捕获异常,至于为什么,可以去看官网,这里不再解释,另外,由于我们数据的一般使用的事务都是-可重复读,所以在这个事务里面如果使用get来查询数据并执行异步任务或者什么,读取的只能是开启事务前的值,但是可以使用on_commit()来执行异步任务(提交事务后执行异步任务)
- 总结,with的用法比装饰器的用法灵活一点,至于用那个,需要具体的场景来考虑