MySQL 数据库一般会并发执行多个事务,多个事务就可能会并发的对相同的数据进行增加、删除、修改和删除操作,这就可能导致出现并发事务的问题,并发事务会有以下四个问题:
对于同一行数据来说,一个事务对该行数据的更新操作覆盖了其他事务对改行数据的更新操作。
本质上是写操作的冲突,解决办法就是让每个事务按照串行的方式执行,按照一定的顺序依次进行写操作。

例如:我们转账的时候,张三的账户余额有100元,当前有两个事务(事务A和事务B),事务A向张三的账户转账100元,事务B向张三的账户转账200元,此时事务A和事务B同时读取到张三的账户余额为100元,事务A和事务B分别更新张三的账户余额。
假设事务A先于事务B提交,而事务A和事务B都提交后的结果是账户余额是300元,也就是说后提交的事务B覆盖了事务A的更新操作。
一个事务读取了另一个事务未提交的数据。
本质上是读写操作的冲突,解决脏读的方法就是先写后读,也就是写完之后再读。

例如:当前有两个事务(事务A和事务B),事务A向张三账户转账100块,事务B查询张三的账户余额,事务A执行转账操作,此时事务A还没有提交,事务B查询到张三的账户多了100元,事务A由于某些原因(服务超时、系统异常或者其他因素)进行了回滚操作,此时事务B查询到的数据就是脏数据。
同一个事务,使用相同的查询语句,在不同时刻读取的数据不一致。
本质上就是读写操作的冲突,解决办法就是先读后写,也就是读完之后再写。

例如:当前有两个事务(事务A和事务B),事务A向张三的账户转账100元,事务B查询张三的账户余额,第一次查询的时候事务A还没有转账成功,第二次查询的时候事务A已经转账成功了,这就会导致事务B两次查询的结果不一致。
一个事务两次读取一个范围的数据记录,两次读取的范围结果不同。
本质上是读写操作的冲突,解决办法就是先读后写,也就是读完之后再写。

例如:当前有两个事务(事务A和事务B),事务A两次查询张三的转账记录,事务B向张三的账户转账100元,事务A在第一次查询的时候事务B还没有转账,事务A第二次查询的时候事务B已经转账成功,这就会导致事务A两次查询的转账记录不一致。
实现事务隔离级别的时候,在可重复读隔离级别中,数据库在第一次读取到数据之后,就会将相应的数据加锁,其他事务无法修改这些数据,此时就能实现可重复读,而这种方法无法对新插入的数据加锁,比如说一个事务A读取了数据或者修改了数据,另一个事务B还是可以对表进行 insert 操作,这就会导致事务A莫名其妙多了一条数据,所以幻读的重点在于插入。
幻读无法通过行级锁来避免,需要使用串行化的事务隔离级别,但这种事务级别会极大的降低数据库的并发能力,所以数据库一般不会使用串行化的事务隔离级别。