并发事务会有哪些问题?
多个事务并发的执行一定会出现相互争夺资源的问题。那么问题具体有哪些呢?
- 脏写(丢失修改)
- 脏读
- 不可重复读
- 幻读
以上这四个问题就是我们需要知道的。但是脏写,由于mysql最低的隔离级别都能避免掉该问题。所以脏写我们就不用去着重去记了。
我们就着重看剩下三个读问题。都是读,大家就更好记了。
首先我们说下脏读。A事务读取到了,B事务中还未提交的修改的数据。如果此时B事务发生了回滚。那么name也就还是原来的值,并没有修改为张三。但此时A事务中已经读到了张三,这就是脏读。
脏读
其次我们来说不可重复读,场景是A事务开启后,在第一次读取name时为王五,但此时B 开启事务修改了name为张三,并提交了(注意此时是提交了事务的)。那么如果A事务再读name,那么就会变成张三。如果此时B再开启事务,再将name修改为李四,并提交。那么A事务再读name,就又变成李四了。再一个事务中多次读取一个数据,结果不一样,那么就产生了不可重复读。 (大家可能有相应的疑惑,别慌等说完后我会解决滴。)
不可重复读
最后是幻读,场景是当A事务中范围查询数据时,此时B中开启事务并添加了新数据,并且满足A事务中查询语句的条件,并且提交了。那么A事务如果还有查询语句再进行查询时,会多出几条数据。此时就出现了幻读。
幻读
经过以上对几个读的讲解,我觉得大家多多少少有很多疑惑。我大胆猜测下。
- 幻读和不可重复读这不是一样的问题吗?只不过是一个是修改语句,一个是插入语句。
- 幻读和不可重复读这算是问题吗?其他事务修改了值并且提交了。难道不应该读取最新的值吗?
- 脏读和不可重复读与幻读感觉是一样的呀,哪儿有区别呢?
问题解答:
1.幻读和不可重复读区别就在事务A中,如果读出的数据是比之前多,不管B事务是增加数据也好,修改数据也罢。都算幻读。如果读出的数据不多,但是不一样了,不一样是指当范围查找时数据变少了,或者精确查找时,返回的数据不一样了。这都是不可重复读。
2.幻读和不可重复读,我们感觉没啥问题。但我们往另外一个方向想。之前我们说过事务的四个特性,其中三个特性都是服务于一个,那就时一致性。我们就从一致性的角度思考,为什么幻读和不可重复读是问题。事务都要满足一致性,从一个状态到另一个状态,我们现在又拿最经典的转账问题,此时A中的事务操作张三和李四,假如A中的事务的一致性是要保证要么张三是1000,李四是1000.要么张三是900,李四是1100.这时A事务中保证的两个状态。那如果此时B事务进来了,修改了李四的存款,把李四的存款改成了500,并提交。那么A事务在进行读取李四的存款时就是500,然后加上100。最终A事务的状态就变成了张三900,李四600。这保证了A事务的一致性吗?没有吧。这儿满足了原子性,操作都是成功的,但是没保证隔离性,进而导致一致性失败。所以幻读和不可重复读算问题的。
3.脏读和不可重复读与幻读,他们都是读到了另外事务修改的数据。但区别就在,脏读他是读的未提交的事务。 而不可重复读和幻读,他们都是读的已提交的事务中修改的数据。这可能就是最大的区别了。