继续昨天的innodb锁的分析:
注:此博文参考一下地址,那里讲的也很详细。http://xm-king.iteye.com/blog/770721
mysql事务的隔离级别分为四种,隔离级别越高,数据安全性越高但是效率越低。
1. Read umcommitted(读未提交):
在该隔离级别内,可以看到其他事务未提交的最新数据。此隔离级别一般并未使用,因为该隔离级别安全要求太低,但效率并未有很大的提高。
容易出现的问题是脏读,具体场景如下:
tx1 | tx2 | |
step1 | select name from table1 where id=1(res:0) | |
step2 | update table1 set name=‘1’ where id=1 | |
3 | select name from table1 where id=1(res:1) | |
4 | rollback; |
说明:在事务一内读到了事务2为提交的数据,但是事务2在提交的时候出现问题,事务回滚;此时事务一仍以事务2未提交成功的数据做处理,就会出现问题,这就是脏读。
2. Read committed(读已提交)
在该隔离级别内,事务看不到其他事务已经提交的数据,只能看到其他事务已提交的数据。此隔离级别是数据库的默认隔离级别。
容易出现的问题是不可重复读,具体场景如下
tx1 |
tx2 |
|
step1 |
select name from table1 where id=1(res:0) |
|
step2 |
update table1 set name=‘1’ where id=1 |
|
3 |
commit |
|
4 |
select name from table1 where id=1(res:1) |
说明:在事物一的两次查询过程中,由于事务二更新了数据,导致事物一两次查询到的数据不一致。
3. Repeatable Read(可重复读)
此隔离级别可以有效的解决不可重复读的问题,但是会出现以下的问题,幻读,示例如下:
tx1 |
tx2 |
|
step1 |
select id from table1 where id<4(res:1,2) |
|
step2 |
insert into table1 (name,id) values (‘name1’,3) |
|
3 |
commit |
|
4 |
select id from table1 where id<4(res:1,2,3) |
在读一定范围内的数据的时候,新插入一条数据,导致两次查到的数据不一致,感觉像是幻影一样,解决方案(粘贴别处的):InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题
4:Serializable(可序列化)
这个是最高的隔离级别,慎用,强行将事务进行排序,使之不会相互冲突,从而解决幻读问题。也就是说,此隔离级别会在查询上强制加一个读锁,在这个级别,可能导致大量的超时现象和锁竞争。
总结(很重要):之前我一直搞不明白读已提交和可重复读两个级别所出现的不可重复度和幻读有什么不同,在冥思苦想和询问同事后终于搞明白了,读已提交级别出现的不可重复读问题,主要指在事务二有update的时候,可重复度解决了以上问题,但是会出现在insert的时候出现幻读。也就是说,不可重复读是update时出现的问题,幻读是insert时出现的问题