初探 Django 事务

本文介绍了Django的事务管理,包括ACID原则的详细解释,以及Django默认的事务行为,如@transaction.atomic装饰器和上下文管理器的使用。文章通过实例探讨了如何在Django中实现数据库事务的原子性、隔离性和持久性。
摘要由CSDN通过智能技术生成

初探 Django 事务

数据库事务(简称:事务)是数据库管理系统(DBMS)执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。试想下面这个例子:

当A需要在商店中购买商品,需花费100元,A通过手机扫码完成支付,涉及到金额的变化如下:

  • 该人账户减少100元
  • 商店账户增加100元

如果这两步不能同时在系统上完成,则有可能出现两种异常情况:

  • 该人账户余额没有减少,商店账户增加100元
  • 该人账户减少100元,商店账户没有增加。

无论是哪一种,对于金融行业来说,都是无法容忍的。如果支付宝频繁出现此类事情,我想大家可能慢慢又会使用纸币或者刷卡吧~

无论是账户增加还是减少,从数据库层面都是几条数据库操作序列的组合。解决此类问题的思路也很简单:

要么需求的一组数据库操作序列都成功,如果其中有一个异常,则此组操作不生效(通常叫做回滚)。

ACID

数据库事务满足 ACID 原则:

  • 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
  • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
  • 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。

相对于上面的付款案例如下:

  • 原子性:确保不管交易过程中发生了什么意外状况(服务器崩溃、网络中断等),不能出现A账户少了100,但商店没到帐,或者A账户没变,但商铺收到了100(数据不一致)。
  • 隔离性:如果A在转账100给商店(T1),同时B又在转账200给A(T2),不管T1和T2谁先执行完毕,最终结果必须是A账户增加100,B账户减少200 。
  • 一致性:确保钱不会在系统内凭空产生或消失。
  • 持久性:确保如果事务1刚刚提交,数据库就发生崩溃,执行的结果依然会保持在数据库中。

原子性

如果需要保证原子性,需要确保一组数据库操作在都成功时才会被提交保存,只要中途有异常,则所有操作都不生效。

begin # 事务开始

update table
update table 
update table
# 任何一个一场都会导致所有 update 撤销

commit # 事务结束,提交

隔离性

关于隔离性的四个强度,有以下四个级别:

  • READ UNCOMMITED :未提交读。未提交的修改对于其他事务是可见的
  • READ COMMITED :提交读。一个事务从开始到提交之前,对于其他事务都是不可读的。
  • REPEATABLE READ:可重复读。Mysql 默认事务隔离级别。同一事物中多次读取同样记录的结果一致。
  • SERIALIZABLE :可串行读。最严格的级别,读写都会上锁。相当于串行执行事务

隔离强度越高,对数据库服务器的 CPU 内存占用越高(管理锁),并行能力也会减弱。应该根据实际情况进行使用。

持久性

如果事务的数据还没有真正被写入磁盘时,数据库服务崩溃了,事务会保证数据不会丢,当管理员重启了数据库后,它会保证:

  • 成功提交的事务,数据会保存到磁盘
  • 未提交的事务,相应的数据会回滚

数据库(以包含Innodb引擎举例)是通过事务日志的方式来达到这两个功能的。

事务的每一个操作(增/删/改)产生一条日志,内容组成大概如下:

  • LSN:一个按时间顺序分配的唯一日志序列号,靠后的操作的LSN比靠前的大。
  • TransID:产生操作的事务ID。
  • PageID:被修改的数据在磁盘上的位置,数据以页为单位存储。
  • PrevLSN:同一个事务产生的上一条日志记录的指针。
  • UNDO:取消本次操作的方法,按照此方法回滚。
  • REDO:重复本次操作的方法,如有必要,重复此方法保证操作成功。

数据库会通过解析事务日志,将修改真正落到磁盘上,随后清理事务日志(正常情况下)

这是数据库在IO与安全性两者权衡的折中方法。如果每次都写入,会占据大量随机的磁盘IO,性能很差。如果每次不写入,服务器崩溃会造成数据丢失。

折中的方法:

  • 将数据的变更以事务日志的方式,按照时间先后追加到日志缓冲区,由特定算法写入事务日志,这是顺序IO,性能较好
  • 通过数据管理器解析事务日志,由特定的算法择机(一般等到较为空
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值