1、读未提交
最容易出现的是脏读,是指当前事务可以读取到其它未提交的事务。举个🌰:
老板张三给员工李四发工资时多打了一个零,本来是发3000的变成发30000,此时的李四正在跟女朋友逛街,查询余额的时候李四菊花一紧,口吐芬芳,大喊一声:卧槽!对着女朋友说:尽管买。但是老板张三发工资的时候事务并没有提交,他立刻进行了事务回滚,竹南打水一场空,李四抱头大哭工资又变成3000了。
这个时候李四读取到的数据就是典型的脏数据,产生的原因是读取了其他未提交的数据。
2、读提交
为了解决脏读的问题,咱们吧事务的隔离级别调整为读提交,它是为了
保证当前事务只能读到其他已经提交完的事务,但是这样会面临个新问题,不可重复读。举个🌰:
李四带着自己心爱的女朋友去商场消费,买单的时候(开启事务),系统检测李四的银行卡里面有5000块钱。这个时候李四的女朋友正在拿李四的手机逛淘宝买衣服一下子买了4000(败家娘们),当李四准备扣费的时候,再次查询余额,发现只剩下1000块钱了,当时李四脸都绿了!!!(这个查询是发生在女朋友买完衣服之后)
像这样的问题,在同一个事务下,李四的金额在不同的时候读取出来的值是不一样的,这就是不可重复度问题。
3、可重复读
在可重复度的情况下,当前事务会禁止其余事务对正在操作的数据进行更新,这样一
来,哎嘿,女朋友消费的事务就要等到李四帐号扣费结束后才能进行,这样不可
重复度的问题就解决了,但是这样一来,又会出现个新的问题,幻读。举个🌰:
李四跟女朋友吵架了,李四伤心欲绝,决定在网上买了个充气娃娃,消费了1000大洋,当晚女朋友查看李四今天的消费记录(开启事务),发现一共消费了1000大洋,这个时候李四发现良心过不去,吧充气娃娃的订单退掉,又花了10000块买了个包包准备为女朋友道歉,(女朋友的事务还在进行中)当女朋友打印李四的消费订单的时候,发现莫名其妙的变成了10000块钱,而且多了一条消费记录。
像这种当前事务还在进行中的时候,由于别的事务进行了删除或者新增的操作,导致当前的数据变多或者变少的情况,就叫做换读。
4、串行化
当事务隔离级别设置为串行化的时候,所有事务都是串行执行的,对应上面的🌰:
女朋友在查看当天消费记录的时候,李四是不允许消费的,这么一来事务并发带来的问题也能得到相对应的解决,但是效率特别低。
5、扩展
用大白话解释了事务的隔离级别之后,想提醒广大程序员:在常用的数据库Oracle默认的事务隔离级别是读提交,MySQL的是可重复读,在MySQL的InnoDB引擎中,虽然事务隔离级别是可重复读,但是也是可以解决幻读滴,背后的原理是在数据行之间添加了间缝锁,是为了防止数据的插入跟删除(没深入研究过),至于具体用那一种事务隔离,要看具体的业务需求啦!