MySQL-什么是事务? 事务的隔离级别有哪些? 什么是脏读、不可重复读、幻读?
什么是事务?
一个事务就是一个完整的、最小的业务逻辑。
假设一个转账需求,A 向 B 转账 100 元,那么:
1. 将 A 账户的钱 - 100 元(update语句)
2. 将 B 账户的钱 + 100 元(update语句)
这就是一个完整的业务逻辑。
以上的操作是一个最小的工作单元,两条update语句必须要求要么同时成功,要么同时失败,才能保证钱的正确。
只有DML语句才会有事务这一说,其它语句和事务无关。
事务其实就是多条DML语句 同时成功 或者 同时失败。
事务是怎么做到多条DML语句同时成功和同时失败的呢?
mysql默认的InnoDB存储引擎支持事务:提供一组用来记录事务性活动的日志文件。
在事务执行的过程中,每一条DML的操作都会记录到 “事务性活动的日志文件” 中。
在事务的执行过程中,我们可以提交事务(commit),也可以回滚事务(rollback)。
提交事务: 清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。提交事务标志着事务的结束。并且是一种全部成功的结束。
回滚事务:将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件。回滚事务标志着事务的结束。并且是一种全部失败的结束。
在mysql如何开启事务、提交事务、回滚事务?
首先,在MySQL中默认自动提交事务,也就是:每执行一条DML语句,则提交一次!
这种自动提交实际上是不符合我们的开发习惯,因为一个业务通常是需要多条DML语句共同执行才能完成的,为了保证数据的安全,必须要求同时成功之后再提交,所以不能执行一条就提交一条。
演示事务:
start transaction; # 开启事务
insert into t_user (name, age) values ('a', 18);
insert into t_user (name, age) values ('b', 19);
commit; # 提交事务, 也可以执行 rollback; 回滚事务
事务有什么特性?
A: 原子性
事务是最小的工作单元。不可再分。
C:一致性
所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。
I:隔离性
一个事务内部的操作和使用的数据对并发的其他事务是隔离的。
D:持久性
一个事务提交后,数据库中数据的更改是永久性的,其他的操作或错误不会对其产生影响。
关于事务隔离性?
事务有 4 个隔离级别:
读未提交(read uncommitted)、
读已提交(read committed)、
可重复读(repeatable read)、
串行化(serializable),
隔离等级依次增加
-
读未提交(read uncommitted)
什么是 读未提交? 事务A 可以读取到 事务B 未提交的数据 这种隔离级别存在什么问题? 脏读现象(Dirty Read) 这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是 读已提交 级别起步! -
读已提交(read committed)
什么是 读已提交? 事务A 只能读取到 事务B 已提交的数据 这种隔离级别存在什么问题? 解决了 脏读现象, 但是存在 不可重复读 即不可重复读取数据,事务A 开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读的时候,读到的数据是4条,3不等于4,称为不可重复读取。 oracle数据库默认的隔离级别 -
可重复读(repeatable read)
什么是 可重复读? 事务A开启之后,不管是多久,只要事务A 没有结束,每一次在事务A中读取到的数据都是一致的。即使事务B 将数据已经修改,并且提交了,事务A 读取到的数据还是没有发生改变,这就是可重复读。 这种隔离级别存在什么问题? 解决了 不可重复读现象, 但是存在 幻读 每一次读取到的数据可能(其他事务可能对这个数据有操作)都是幻象。不够真实! mysql中默认的事务隔离级别 -
串行化(serializable)
什么是 串行化? 这是最高隔离级别,这种隔离级别表示事务排队,不能并发! 这种隔离级别存在什么问题? 解决了所有的问题。每一次读取到的数据都是最真实的,但是效率是最低的。
对MySQL隔离级别进行操作?
select @@tx_isolation; # 查看隔离级别
set global transaction isolation level read uncommitted; # 设置隔离级别为 读未提交

浙公网安备 33010602011771号