mysql隔离级别

最近在公司项目上遇到一个问题,客户使用某个功能经常出现重复数据,后面经排查,发下这个功能因为设计到递归,而且是一个粒度比较大的事务,

操作比较耗时,mysql数据库使用了默认的隔离级别RR,因此上一个用户操作后事务没有完成,下一个用户又重复操作了,数据被重复写入了.

解决方案是后来在事务执行之前加了一个表,用来记录操作数据id,保存前进行判断是否有记录,有则直接返回,没有则保存记录执行事务后删除记录.

现在我们来重现一下这种场景

首先新建一张表

 

 

 新建三个窗口连接数据库测试

 

 

 1.读未提交RC

两个窗口连接上数据库,开启事务,查询t_user表

 

 

 

 

 

 窗口2更新t_user表

 

 

 此时窗口3再执行查询语句,发现读到了事务没有提交的脏数据,这种情况称之为"脏读"

 

 

 把窗口二和三的mysql退出(一定要退出,否则修改隔离级别在当前会话不生效)

2.读已提交

窗口一修改隔离级别

 

 

 窗口二/三连接数据库开启事务查询

 

 

 

 

 

 窗口二更新表数据

 

 

 窗口三执行查询,发现数据没有变化

 

 

 窗口二提交事务,窗口三执行查询;

 

 

 

 

 

 这时候,我们会发现窗口三读到了窗口二提交的数据,顾名思义这种场景的隔离级别就是读已提交,在这个隔离级别下,在同一个事务中执行了两次相同查询语句的到了不一样的结果,这种现象叫"不可重复读"

3.可重复读RR

这种隔离级别解决了读已提交出现的"不可重复读"的问题,所以称之为可重复读.是mysql的默认隔离级别;

 

 

 开启事务 查询

 

 

 

 

 

 

窗口二更新

 

 

 窗口三读不到更新记录

 

 

 窗口二提交事务,窗口三查询,依旧查询不到数据

 

 

 

 

 在这个隔离级别下会出现幻读的场景

窗口二/三开启事务,窗口二插入一条数据并提交

 

 窗口三查询数据,查不到窗口二提交的数据,但是当窗口三执行update语句时会发现有update了两条数据

 再次查询,查到了数据

 

posted @ 2023-03-01 15:45  佳琪如梦  阅读(41)  评论(0)    收藏  举报