前言
大家好,我是程序蛇玩编程。
Mysql中事务大家不陌生吧,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。那它具有哪些特性,如何实现的呢?接着往下看。
正文
事务的特性:
事务的基本特性主要为四种,原子性,一致性,隔离性,持久性,下面一一介绍:
1.原子性(Atomicity):事务是数据库的逻辑工作单位,事务中包含的各操作要么全部成功,要么全部失败。如果事务中的某个操作失败,整个事务将回滚(Rollback),撤销所有已执行的操作,返回到事务开始前的状态。
2.一致性:一致性状态是指数据库中的数据应满足所有预定义的规则和约束,例如实体完整性、参照完整性等。
3.隔离性:并发执行的事务之间不会相互影响,每个事务都感觉不到其他事务的存在。事务的隔离性有不同的级别,包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。
4.持久性:一旦事务被提交(Commit),它对数据库的修改就是永久性的,即使系统发生故障也不会丢失。
今天主要向大家介绍隔离性,他能解决什么问题呢? 假如事务没有隔离性的话,多个事务同时执行的时候就可能出现脏读、不可重复读、幻读的问题,于是就诞生了隔离性,它有如上述的四种隔离级别。
1.读未提交是指,一个事务可以读取到其他事务未提交的数据。
2.读提交是指,一个事务只能读取到其他事务已经提交的数据。
3.可重复读是指,它确保了一个事务在执行期间可以多次读取相同的数据集,而不会看到其他并发事务对这些数据所做的更改。
4.串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
其中"读提交"和"可重复读"较难理解,我举了一个例子如下图所示,假设数据表S只有一列,一行的值为1,两个事务按照时间顺序执行。
我们来看看事务A在不同的隔离级别下,分别返回什么结果。
若隔离级别是"读提交",则a1是1,a2是2,事务B的更改在提交后才能被事务A看到,所以a3也是2。
若隔离级别是"可重复读",则a1,a2都是1,a3才是2,之所以a2是1,遵循的就是这个要求:事务在执行期间看到的数据前后必须是一致的。
那如何做到事务看还是看不见的呢?
数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。而在“读提交”隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。
事务隔离的实现:
在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。
我们假设一个值从10被按顺序改成了11,12,13,在回滚日志(undolog)中有如下记录:
当前值是 13,但是在查询这条记录的时候,不同时刻启动的事务会有不同的 视图。视图 A、B、C 里面,这一个记录的值分别是 10、11、13,同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。
今日小结
今天简单给大家介绍了事务的四大特性,并用一个例子说明了不同隔离级别下事务查询返回的结果,最后述说了事务隔离的实现,讲到了回滚日志以及视图,下一期我们再会。很多八股文内容合集就来这哈。