`
星夜的遐想
  • 浏览: 190525 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MySQL踩得的坑

阅读更多

 

一、可重复读

 

Oracle的默认隔离级别为  READ COMMITTED ,而MySQL的默认隔离级别为 REPEATABLE READ 感觉MySQL的隔离级别还要高些,从理论上来讲更安全,但是。。

 

经过测试发现,虽然保证了可重复读的表象(一个事务中两次的读取的结果都是一致的),之前以为可重复读时,可以阻止其他事务进行修改,但是经过验证

 

 

1、查看数据库的隔离级别

SELECT @@tx_isolation;

-----------------

 

REPEATABLE-READ  

 

 

 

2、模拟两个客户端进行操作,在工具中,需要打开两个连接,而不是查询窗口。

 

  客户端A  

 

 

SET autocommit=0;

START TRANSACTION;

-- 第一次查询
SELECT * FROM t1;

-- 第二次查询(在客户端B执行完成后,再单独执行该语句)
SELECT * FROM t1;

 

 

    客户端B执行

 

 

SET autocommit=0;

START TRANSACTION;

UPDATE  t1 SET a =99 WHERE b=3000;

COMMIT;

 

 

    验证结果发现,即使在A事务执行过程中数据被B事务修改了,但是A的数据还是没有变化,虽然解决了两次读取数据不一致的问题,但是隐患更大,都不知道有没有被修改,因此直接取数来进行处理其实还是有问题的

 

问题虽然可以通过 读锁(共享锁)实现 LOCK IN SHARE MODE

 

如:SELECT * FROM t1 WHERE a=50 LOCK IN SHARE MODE 

 

这样就可以阻止其他事务,进行新增,修改,删除,如果a建了索引,锁的条件为a的记录;如果没有建索引锁的是整张表,其他记录也不能修改了;必须等到此事务提交才行,所以觉得还不如事务隔离级别设置为READ COMMITTED,虽然会出现不可重复读现象,但是至少每一时刻取的数据是真实的

 

 

 

 

二、MySQL的innoDB存储引擎支持的是行锁

 

经过验证发现,只有只有修改条件走索引才锁记录,否则会锁表。

验证语句可以参考附件

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics