这里是淡沫初夏zz学习之路
如果这篇文章对你有帮助,给博主一个免费的点赞以示鼓励吧
⭐更多文章请关注 淡沫初夏zz主页
欢迎各位点赞评论收藏⭐
冲冲冲
上一篇文章:高级SQL查询
这篇文章主要介绍MySQL中的事务,事务在MySQL中是非常重要的,同时在面试时面试官也会询问,事务的特性,隔离性,以及脏读,幻读,不可重复读的问题!!
事务(Transaction)是将⼀组操作封装成⼀个执⾏单元(封装到⼀起),这⼀个执⾏单元要么⼀起执⾏成功,要么⼀起失败,不会出现执⾏“⼀半”的情况如果单元中某条sql语句一旦执行失败或者产生错误,整个单元将会回滚,也就是所有受到影响的数据将会返回到事务开始以前的状态;如果单元中的所有sql语句均执行成功,则事务被顺利执行。
以银行转账为例,A 转账 B 转账,那么它的执⾏流程是这样的:
A 账户 -500
B 账户 +500
试想⼀下,如果执⾏了⼀半,断点了或者程序崩溃了,那么 A 账号的钱就永久消失了?那怎么办?⽤事务就可以解决,封装成⼀个执⾏单元,要么⼀起成功,要么⼀起失败。
1.开启事务(start transaction)。
2. 执行多条 SQL。
3. 提交/回滚事务(commit/rollback)。
比如上面的张三给李四转账,咱们的事务执行SQL 如下:
– 开启事务
start transaction;
– 张三账户减少500
update account set money=money-500 where name = ‘张三’;
– 李四账户增加500
update account set money=money+500 where name = ‘李四’;
– 提交事务
commit;
注意:当事务开启后,就要使用提交事务commit或回滚事务rollback去结束
事务有4 大特性ACID,原子性、持久性、⼀致性和隔离性
又称不可分割性,事务里所有的操作要么全部成功,要么全部失败原⼦性是事务最重要的特性,全部执⾏失败并不是不执⾏,⽽是通过逆操作 rollback(回滚)数据。
实现原理:回滚是逆 SQL 操作:⽐如 A 账户 -500 元的逆操作就是 A 账户 +500 元。
事务在执行前后的数据必须保持一种合法的状态,也就是从一个一致状态,到达另一个状态
举例:比如转账操作,转账之前两个账号的总额是 100 元(各个 50 元),那么两个账户相互转账之后的钱总额也是 100 元,也就是事务总是从⼀个⼀致状态到另⼀个⼀致状态,不会说转账之前是100 元,相互转账之后变成 80 了,这就不符合⼀致性了。
事务执行之后,它所做的所有修改都是永久的(不会丢失),不会因为事务执行后,数据丢失,比如数据存储到磁盘中就是持久的,不会丢失的,不会因为电脑重启而丢失
又称独立性,当有多个事务并发进行时,事务之间直接进行隔离,就是一个事务发生,对另一个不影响
举例说明:⽐如宠物店,如果宠物店来了⼀个狗狗,那么是可以正常的处理它的诉求的,⽐如打个疫苗啊、美个容啊都是可以很顺利的完成的,但是如果⼀个 20 平⽅的宠物商店来了 20 只狗那它们就得打起来了,这个时候怎么办?把它们装到笼⼦⾥⾯“隔离”起来啊,这和咱们的事务的隔离性是⼀样的,都是解决多个事务同时请求的问题的
MySQL 隔离性对应的隔离级别有以下 4 种,这就像隔离狗的笼⼦有各个级别的⼀样,有大的、有小的、有不透光的,有透光的等等
也叫未提交读,该隔离级别的事务,可以读取其他事务中未提交的数据,因为可以看到读取到其他事务中未提交的数据,⽽未提交的数据可能会发生回滚,因此我们把该级别读取到的数据称之为脏数据,把这个问题称之为脏读
「脏读」: 脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并不一定最终存在的数据,这就是脏读。
「不可重复读」: 不可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据出现不一致的情况。
「幻读」: 幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。
也叫提交读,该隔离级别的事务能读取到已经提交事务的数据,因此它不会有脏读问题。但由于在事务的执⾏中可以读取到其他事务提交的结果,所以在不同时间的相同 SQL 查询中,可能会得到不同的结果,这种现象叫做不可重复读
是 MySQL 的默认事务隔离级别,它能确保同⼀事务多次查询的结果⼀致。但也会有新的问题,比如此级别的事务正在执行时,另⼀个事务成功的插⼊了某条数据,但因为它每次查询的结果都是⼀样的,所以会导致查询不到这条数据,⾃⼰重复插⼊时又失败(因为唯⼀约束的原因)。明明在事务中查询不到这条信息,但⾃⼰就是插⼊不进去,这就叫幻读
事务最⾼隔离级别,它会强制事务排序,使之不会发生冲突,从而解决了脏读、不可重复读和幻读问题,但因为执行效率低,所以真正使用的场景并不多
MySQL 的隔离级别有 4 种:
1 读未提交(read uncommitted):有脏读、不可重复读、幻读问题。
2 读已提交(read committed):有不可重复读、幻读问题。
3 可重复读(repeatable read):有幻读问题,MySQL 默认的隔离级别。
4 序列化(serializable):⽆任何问题,性能低。