[MySQL]对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解
2017-01-09 10:50
851 查看
一、缘由
众所周知MySQL从5.5.8开始,Innodb就是默认的存储引擎,Innodb最大的特点是:支持事务、支持行级锁。既然支持事务,那么就会有处理并发事务带来的问题:更新丢失、脏读、不可重复读、幻读;相应的为了解决这四个问题,
就产生了事务隔离级别:未提交读(Read uncommitted),已提交读(Read committed),可重复读(Repeatable read),可序列化(Serializable)。
之前在看事务隔离级别的时候,基本是一知半解。再次碰到,还是浆糊,所以这里打算彻底搞明白、清楚,也好后续的学习。
二、解决办法:
1、概念说明:更新丢失:最后的更新覆盖了其他事务之前的更新,而事务之间并不知道,发生更新丢失。更新丢失,可以完全避免,应用对访问的数据加锁即可。
脏读:(针对未提交的数据)一个事务在更新一条记录,未提交前,第二个事务读到了第一个事务更新后的记录,那么第二个事务就读到了脏数据,会产生对第一个未提交
数据的依赖。一旦第一个事务回滚,那么第二个事务读到的数据,将是错误的脏数据。
不可重复读:(读取数据本身的对比)一个事务在读取某些数据后的一段时间后,再次读取这个数据,发现其读取出来的数据内容已经发生了改变,就是不可重复读。
幻读:(读取结果集条数的对比)一个事务按相同的查询条件查询之前检索过的数据,确发现检索出来的结果集条数变多或者减少(由其他事务插入、删除的),类似产生幻觉。
2、不可重复读和幻读的区别:
不可重复读
重点是修改:同样的条件下,你读取过的数据,再次读取发现值不一样了。
例子:(只是为了说明区别,没有事务隔离级别约束)
事务1:Jack读取自己的工资为1000,事务并没有结束:
select salary from employee empId ="Jack";
事务2:财务人员修改了Jack的工资为2000,并提交事务(事务1不知道):
update employee set salary = 2000;
commit;
在事务1中,再次读取Jack的工资时,工资变为2000
select salary from employee empId ="Jack";
在一个事务中前后两次读取的结果值并不一致,导致了不可重读读
幻读
重点在于新增或者删除(数据条数的变化):同样条件下,第一次和第二次读出来的记录条数不一样。
例子:
目前工资为1000的员工有10人。
事务1:读取所有工资为1000的员工,事务进行中
select count(*) from employee where salary = 1000;
共读取到10条记录。
事务2:同时插入一条新的员工记录,工资也为1000
insert into employee(empId, salary) values('Tom', 1000);
commit;
事务1:再次读取所有工资为1000的员工
select count(*) from employee where salary = 1000;
共读取到了11条记录,这样就像产生了幻读。
三、事务隔离级别:
并发处理带来的问题中,更新丢失可以完全避免,由应用对数据加锁即可。脏读、不可重读度、幻读,其实都是数据库的一致性问题,必须由一定的事务隔离机制来解决。其中一种方法是:不用加锁,通过一定的机制生成一个数据请求时间点的一致性快照,并用这个快照来提供一个界别的一致性读取。从用户的角度看,好像是数据库提偶拱了
统一数据的多个版本。这种技术叫做:数据库多版本并发控制,MVCC 多版本数据库。
事务隔离的本质是使事务在一定程度上串行化执行,显然和并发机制是矛盾的。数据库的事务隔离越严格,并发负作用越小,代价越高(影响并发访问了呗)。
为了解决隔离和并大的矛盾,IOS SQL92规定了4个隔离级别。(隔离==串行)
MySQL 默认的级别是:Repeatable read 可重复读。
相关文章推荐
- Mysql事务,并发问题,锁机制-- 幻读、不可重复读(转)
- 数据库并发事务存在的问题(脏读、不可重复读、幻读等)
- hibernate事务并发问题(脏读,不可重复读,幻读)
- 数据库并发导致的脏读 不可重复读 幻读的处理方法
- 事务的并发处理带来的问题
- 理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
- 理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
- 并发事务处理带来的问题
- MySQL(25):事务的隔离级别出现问题之 不可重复读
- 对于脏读,不可重复读,幻读的一点理解,看懂红字很关键
- 事务并发处理带来的问题
- 事务的脏读、幻读、不可重复读的理解
- 理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
- 事务和线程的区别还有事务并发执行引起的四个问题:丢失修改、脏读、不可重复读,幻读
- 数据库---并发控制及其带来的问题丢失修改,读脏数据,不可重复读及解决(程序员级)
- MYSQL事务避免脏读、不可重复读、幻读
- Hibernate事务与并发问题处理
- Hibernate事务并发问题处理(乐观锁与悲观锁)
- 多角度彻底理解数据库事务中的"脏读"."不可重复的读"及"虚读"
- Hibernate事务与并发问题处理(乐观锁与悲观锁)