Phantom Read和Serializable

在Repeatable Read隔离级别下,一个事务可能会遇到幻读(Phantom Read)的问题。

 

幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。

 

它和不可重复读(Non Repeatable Read)的区别就是:

 

不可重复读:两次读取之间,其他事务对于某一行数据的修改或者删除造成。这个行级锁就可以解决了。

 

而幻读(Phantom Read):两次读取之间,其他事务添加了一行数据。表级锁才可以解决。

 

但是在实际开发中,表级锁我们基本上是您能不用就不用的,就是行级锁,都是需要慎用的。

 

我们接着使用employees表的数据:

 

然后,分别开启两个MySQL客户端连接,按顺序依次执行事务A和事务B:

 

第一步:执行事务A,SELECT * FROM employees WHERE employee_id= 99;

 

第二步:执行事务B,INSERT INTO employees (employee_id, last_name) VALUES (99, 'Test');

 

第三步:执行事务B,COMMIT;

 

第四步:执行事务A,SELECT * FROM employees WHERE employee_id = 99;

 

第五步:执行事务A,UPDATE employees SET last_name = 'Ace' WHERE employee_id = 99;

 

第六步:执行事务A,SELECT * FROM employees WHERE employee_id = 99;

 

第七步:执行事务A,COMMIT;

 

事务B在第1步第一次读取id=99的记录时,读到的记录为空,说明不存在employee_id =99的记录。随后,事务A在第2步插入了一条employee_id =99的记录并提交。事务B在第4步再次读取employee_id =99的记录时,读到的记录仍然为空,但是,事务B在第5步试图更新这条不存在的记录时,竟然成功了,并且,事务B在第6步再次读取employee_id =99的记录时,记录出现了。

 

可见,幻读就是没有读到的记录,以为不存在,但其实是可以更新成功的,并且,更新成功后,再次读取,就出现了。

 

Serializable是最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。

 

虽然Serializable隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用Serializable隔离级别。

 

默认隔离级别

如果没有指定隔离级别,数据库就会使用默认的隔离级别。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值