目录
一, 事务的特性
二, 数据库中开启事务
三, Django 中开启事务的两种方式
第一种
第二种
四, 事务的隔离级别
隔离级别
如何查看 MySQL 隔离级别?
修改事务的隔离级别
隔离级别解释
- read uncommited (可读未提交, 脏读)
- read committed(读提交, 不可重复读)
- repeated read(可重复读, 可重复读)
- serializable(串行化, 幻读)
一, 事务的特性
A. 原子性 atomicity : 不可分割, 要么都做, 要么都不做.
C. 一致性 consistency : 数据库从一个一致性状态变到另一个一致性状态, 一致性与原子性是密切相关 (总量不变)
I: 隔离性 isolation : 一个事务的执行不能被其他事务干扰
D: 持久性 durability : 永久性, 事务一旦提交, 就已经改变了数据库中的数据. 不可回滚
二, 数据库中开启事务
- 1.# 修改数据之前先开启事务操作
- start transaction;
- 2.# 修改操作
sql 语句
- 3.# 回滚到上一个状态, 未保存. 数据在内存中
- rollback;
- 4.# 开启事务之后, 只要没有执行 commit 操作, 数据其实都没有真正刷新到硬盘
- commit; # 相当于保存, 数据刷到硬盘
三, Django 中开启事务的两种方式
第一种
- from django.db import transaction
- with transaction.atomic():
- ...
第二种
- from django.db import transaction
- @transaction.atomic
- def post(self,request):
- ...
- sid=transaction.savepoint() #开启事务
- ...
- transaction.savepoint_rollback(sid) # 回滚
- ...
- transaction.savepoint_commit(sid) # 提交
四, 事务的隔离级别
隔离级别
read uncommited (可读未提交, 脏读): 不做任何隔离, 具有脏读, 不可重读对, 幻读的问题
read committed (读提交, 不可重复读): 可以防止脏读, 不能放在不可重复读和幻读的问题
repeated read(可重复读, 可重复读): 可以防止脏读, 不可重复读, 不能放在幻读 (MySQL 的默认隔离级别)
serializable(串行化, 幻读): 数据库运行为串行, 以上问题都可以防止, 但是性能低
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
**1, 脏读: 事务 A 读取了事务 B 更新的数据, 然后 B 回滚操作, 那么 A 读取到的数据是脏数据 **
**2, 不可重复读: 事务 A 多次读取同一数据, 事务 B 在事务 A 多次读取的过程中, 对数据作了更新并提交, 导致事务 A 多次读取同一数据时, 结果 不一致.**
**3, 幻读: 系统管理员 A 将数据库中所有学生的成绩从具体分数改为 ABCDE 等级, 但是系统管理员 B 就在这个时候插入了一条具体分数的记录, 当系统管理员 A 改结束后发现还有一条记录没有改过来, 就好像发生了幻觉一样, 这就叫幻读.**
** 小结: 不可重复读的和幻读很容易混淆, 不可重复读侧重于修改, 幻读侧重于新增或删除. 解决不可重复读的问题只需锁住满足条件的行, 解决幻读需要锁表 **
### read uncommited(可读未提交, 脏读)
如何查看 MySQL 隔离级别?
select @@global.tx_isolation;
修改事务的隔离级别
- # 修改配置文件
- transaction-isolation=Read-Committed
- # 修改后一定要重启数据库
隔离级别解释
下面的解释都用这个 user 表
name | age |
---|---|
jeff | 38 |
read uncommited (可读未提交, 脏读)
脏读 (两个事务都是存活的)
1 a 开启事务 将 jeff 的年龄改成 18 岁, 但是没有提交事务
2 b 开始事务 读取 jeff 的年龄, 发现是 18 岁.
上述的问题,
假设 a 事务回滚, b 事务使用的数据就是错误的, 就导致程序数据不正确.
read committed(读提交, 不可重复读)
不可重复度 (两个事务都是存活的)
1 a 开始事务 将 jeff 的年龄改成 18 岁, 但是提交了
2 b 开启事务 读取 jeff 的年龄就能读取 a 事务修改后的 jeff 年龄 18 岁.
上述的问题,
只能读提交后的数据, 事务 a 事先读取了数据, 事务 b 紧接着更新了数据, 并提交了事务, 而事务 a 再次读取该数据时, 数据已经发生了改变.
repeated read(可重复读, 可重复读)
可重读读 (两个事务都是存活的)
a 开始事务 将 jeff 的年龄改成 18 岁, 但是提交了
b 开启事务 读取 jeff 的年龄不能读取 a 事务修改后的 jeff 年龄 18 岁. 而是读取的是 38 岁
serializable(串行化, 幻读)
幻读 (两个事务都是存活的)
# 概念和不可重读有点像, 不可重复度是站在修改的基础上, 而幻读是站在新增的基础上
1 a 开始事务 将所有的的年龄改成 18 岁
2 b 开始事务 新增一条数据数据 name=tank,age=19, 而且提交了.
3 a 重新查, 发现有一条数据 的 age=19, 这就是所谓的幻读.
来源: https://www.cnblogs.com/guyouyin123/p/12512920.html