本文主要是介绍MySQL综合应用二:事务机制二:四种隔离级别:【READ UNCOMMITTED】、【READ COMMITTED】、【REPEATABLE READ】、【SERIALIZABLE】;,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
1.买票的业务场景:适合【READ UNCOMMITTED】的隔离级别
2.银行转账的业务场景:适合使用【READ COMMITTED】这种隔离级别
3.电商订单支付场景:适合使用【REPEATABLE READ】这种隔离级别
4.【SERIALIZABLE】隔离级别
数据库中的事务都是并发执行的,因为事务具有隔离性,会给一些业务带来问题。本篇博客主要介绍【事务并发执行的条件下,怎么去修改事务的隔离级别,以满足业务的要求。】
默认情况下,MySQL是不允许事务之间相互读取临时数据的,但是在某些特殊场合下,我们需要允许事务之间能读取到一些临时数据,这个就必须去修改事务的隔离级别了。
需要根据具体的业务场景,从这四个隔离级别中提挑选合适的一个来使用。
1.买票的业务场景:适合【READ UNCOMMITTED】的隔离级别
业务案例1:A事务看到G8047 1车厢1A坐席是未售出状态,于是A事务就使用UPDATE语句修改了这条记录的状态为已售出,因为A事务还没有提交,所以修改操作只是记录在了redo日志中,真实的数据并没有发生改变。。。。如果,此时B事务启动了,B事务也会看到G8047 1车厢1A坐席是未售出的,于是B事务使用UPDATE修改了这条记录的状态为已售出,然后B事务很快就提交了,于是真实的数据文件就发生了改变。。。。此时,A事务再去提交事务,就发现这个坐席已经是已售出了,于是A事务就引发了回滚操作。
虽然,这个案例中没有产生歧义的数据,但是动不动就购票失败,这种体验很差;;;于是在这种场景中,就应该允许当前的事务去读取其他事务的临时状态,B事务发现A事务的临时数据中已经购买了G8047 1车厢1A坐席的信息,于是B事务就可以去购买其他的坐席了;
对于【买票的业务】这种场景,适合使用“READ UNCOMMITTED”这种隔离级别,意思是:允许事务读取其他事务未提交的临时数据;
其中,“SET SESSION”意思是,设置当前会话的事务隔离级别;这种设置不是全局的,只在当前会话生效;会话的意思是:在Navicat中打开一个SQL面板,编写SQL语句,这个就是一个会话,当把这个面板关了,这个会话就结束了;
演示:
So,如果想让某个事务能够看到其他事务的临时数据,应该怎么做?
2.银行转账的业务场景:适合使用【READ COMMITTED】这种隔离级别
银行转账之类的业务,绝对不能让某个事务去读取其他事务没有提交的临时数据;
比如业务案例2:银行转账类业务,只能让当前事务去读取其他事务提交以后的数据,绝对不能读取其他事务没有提交的临时数据;比如Scott账户原有5000元,A事务开启了同时还没有来得及做任何操作,此时Scott账户有消费行为,B事务将账户余额改成了100块,然后A事务向Scott转账1000元了,如果A事务读取了B事务的临时数据,A事务执行完毕之后,Scott账户余额是4900元。。。如果A事务和B事务都正常COMMIT了,最终的余额是4900元,是没有问题的。。。但是,如果B事务是一笔错误的消费,需要ROLLBACK,但由于允许A事务读取B事务的临时数据,所以最终Scott账户余额是4900元,出错了。。。
对于【银行转账】这种场景,适合使用“READ COMMITTED”这种隔离级别,意思是:当前事务只能读取其他事务已经提交的数据,未提交的临时数据是读取不到的;
演示:
3.电商订单支付场景:适合使用【REPEATABLE READ】这种隔离级别
比如“业务案例3”:比如在京东商城中,顾客下单之后在支出订单之前,卖家给商品涨价啦,顾客应该按照涨价之前的价格支付;;;所以,在这个业务场景中,我们希望当前事务的执行不要受到其他事务的影响,甚至其他事务提交以后的结果也不要影响到当前事务。。。这个事务的隔离级别就是【REPEATABLE READ】,这种隔离级别意味着,当前的事务能读到的数据是事务开始之前的数据,事务开启之后,其他事务提交的数据是读不到的;
这种隔离级别的底层实现:事务执行之前,会把数据copy到undo日志中,一个隔离级别是【REPEATABLE READ】的事务只会去读取undo日志中的属于自己的那部分数据;
电商订单支付场景:适合使用【REPEATABLE READ】这种隔离级别;
案例:
下面需要说明一点:一个事务在执行select操作之后,才能把数据表中的数据copy到undo日志中;;;即下面的事务,如果在【上面的将sal设置为1的事务】提交之前没有select,当【上面的将sal设置为1的事务】提交之后,下面这个事务再第一次执行select的话,其查询的结果就是sal已经被设置为1的t_emp表的数据了;(好吧,undo日志和redo日志的原理需要了解一下。。。。)
MySQL数据库默认的事务隔离级别就是【REPEATABLE READ】;即在新的会话中,没有特意通过【SET SESSION TRANSACTION ISOLATION LEVEL ******】去修改事务隔离级别的话,事务的隔离级别就是【REPEATABLE READ】。
4.【SERIALIZABLE】隔离级别
序列化隔离级别:一旦设置了这种隔离级别后,当前会话里的事务,需要等待其他事务执行结束之后,才可以执行,不再会出现并发执行的事务了;虽然序列化执行事务能避免一切业务场景上的问题,但是随之而来的是数据库的并发性能急剧下降;;;;;所以,这种隔离级别是很少使用的;
演示:
可以发现,序列化隔离级别不太好用。。。
这篇关于MySQL综合应用二:事务机制二:四种隔离级别:【READ UNCOMMITTED】、【READ COMMITTED】、【REPEATABLE READ】、【SERIALIZABLE】;的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!