MySQL事务
事务就是把多个步骤,多个操作,打包成一个步骤,一个操作,其中任意一个步骤执行失败,都会进行回退,使这里的影响被降到最低
数据库上涉及到很多和事务相关的操作,最典型的就是转账
要么两个都执行完,要么一个都不执行,此处的“一个都不执行”不是真的没执行,而是通过恢复的方式,把之前操作造成的影响给还原
还原的方式叫“回滚”,rollback;
事务的基本特性
原子性
最核心的特性
事务是最小的执行单位,不允许分割。原子性确保动作要么全部完成,要么完全不起作用;
一致性
数据是对的,没有纰露
执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
持久性
事务进行的操作都会写磁盘,只要事务执行成功,造成的修改就是持久化的
隔离性
描述多个事务并发执行的时候所产生的情况
并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障
数据库中的事务彼此之间也是可能相互影响的,事务的隔离性也就是在描述事务执行过程中,影响情况能接受到啥程度
一个数据库服务器可以给多个客户端提供服务,这个时候就可能会涉及到多个客户端同时操作同一个表,就可能产生这种并发事务的情况
售票系统只剩一张票,但是客户端和小程序同时售卖,就有一定概率把这个票给抢成-1
上述问题,就是两个事务之间产生了干扰和影响,为避免相互干扰,就引入了隔离性,通过隔离性来降低上述的影响,为啥要并发执行,目的是为了提高效率,提高隔离性,带来的问题是数据更准了,但是效率更低了。
并发执行事务时产生的问题
1.读脏数据
一个事务读取数据并且对数据进行了修改,这个修改对其他事务来说是可见的,即使当前事务没有提交。这时另外一个事务读取了这个还未提交的数据,但第一个事务突然回滚,导致数据并没有被提交到数据库,那第二个事务读取到的就是脏数据
2.丢失修改
在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改
3.不可重复读
事务B读取过程中,事务A进行了修改,没有直接修改B读取的数据,但是影响了B读取的结果,事务B两次读取到的结果集不一样
4.幻读
不可重复读的重点是内容修改或者记录减少比如多次读取一条记录发现其中某些记录的值被修改;
幻读的重点在于记录新增比如多次执行同一条查询语句(DQL)时,发现查到的记录增加了。
事务的隔离级别
为了解决并发执行事务带来的问题,MySQL等数据库引入了“隔离级别”,可以让用户自行选择一个适合自己当前业务场景的级别
READ-UNCOMMITTED(读取未提交)
最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
READ-COMMITTED(读取已提交)
允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
REPEATABLE-READ(可重复读)
对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
SERIALIZABLE(可串行化)
最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。