mysql四种隔离级别:

  • READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
  • READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
  • REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读

读未提交场景:

甲开启一个事务中查询自己的银行账户,显示账户金额是5000。

此时乙打开一个事务往甲的银行卡里面转入500,但是未进行事务提交,此时打电话给甲,让他查询自己的银行余额。

甲再次查询显示的是5500,这个时候就发生了脏读,读取到别人事务未提交的数据;

乙打完电话,把数据进行回滚,甲的账户又变回5000元,此时提交,事务结束。

读取已提交场景:

甲开启一个事务中查询自己的银行账户,显示账户金额是5000。

此时乙开启一个事务往甲的银行卡里面转入500,但是未进行事务提交,此时打电话给甲,让他查询自己的银行余额。

甲再次查询显示的仍然是5000,这是因为READ-COMMITTED隔离级别是只能读取到已经提交的事务,没有提交的事务是不能读取到的。

甲说:我这边没有收到500,乙此时进行提交事务,说你再看下;甲再次进行查询,发现账户确实变成5500了,此时甲提交了事务;

但是这个时候就发生了不可重复读的现象;甲在一个事务中前后读取的数据发生不一样了;

可重复读场景:

甲开启一个事务中查询自己的银行账户,显示账户金额是5000,count下自己关于乙的转账记录,发现是0条;

此时乙打开一个事务往甲的银行卡里面转入500,但是未进行事务提交,此时打电话给甲,让他查询自己的银行余额。

甲再次查询显示的仍然是5000,这是因为READ-COMMITTED隔离级别在同一个事务中只能读取到已经提交的事务,没有提交的事务是不能读取到的。

甲说:我这边没有收到500,乙此时进行提交事务,说你再看下;甲再次进行查询,账户仍然显示5000,这就是可重复读,每次读取的数据都是一样的,甲未提交事务,在同一个事务中多次读取同一个数据值是不变化的(无论改数据是否发生过事务提交,跟不可重复读的差别就在此处);

甲说:你到你到底给我转账了没有,乙说我已经转账了,而且也提交事务了;然后甲明白了,他进行count,发现自己关于乙的转账记录有1条,这就发生了幻读现象;(如果甲此时提交事务,重新查询,账户就是5500了)

可串行化场景:

这个大家都明白,我就不说了