重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
脏读就是指读到还没完全弄好的数据。避免脏读的办法就是采取事务,使得他用户正在更新时锁定数据库,阻止你读取,直至全部完成才让你读取。
为平湖等地区用户提供了全套网页设计制作服务,及平湖网站建设行业解决方案。主营业务为成都网站建设、网站设计、平湖网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅是存储和管理数据,而转变成用户所需要的各种数据管理的方式。数据库有很多种类型。
数据库是一个单位或是一个应用领域的通用数据处理系统,它存储的是属于企业和事业部门、团体和个人的有关数据的集合。数据库中的数据是从全局观点出发建立的,按一定的数据模型进行组织、描述和存储。其结构基于数据间的自然联系,从而可提供一切必要的存取路径,且数据不再针对某一应用,而是面向全组织,具有整体的结构化特征。
mysql事务隔离级别如下:
1.读取未提交(READ-UNCOMMITTED):最低的隔离级别,允许读取尚未提交的数据变更,可能造成脏读、不可重复读、幻读。
2.读取已提交(READ-COMMITTED):允许读取并发事务已经提交的数据,可以避免脏读,但是可能造成不可重复、幻读。
3.可重复读(REPEATABLE-READ):对同一字段多次读取的结果都是一致的,除非本身事务修改,可以避免脏读和不可重复读,但是可能造成幻读。
4.可串行化(SERIALIZABLE):最高的隔离级别,完全服从ACID的隔离级别,所以的事务依次执行,可以避免脏读、不可重复读、幻读。
事务的特性:
1.原子性:事务最小的执行单位,不允许分割。事务的原子性确保动作要么全部执行,要么全部不执行。
2.一致性:执行事务的前后,数据保持一致。例如转账的业务中,无论事务是否成功,转账者和收款人的总额应该是不变的。
3.隔离性:并发访问数据库时,一个用户的事务不应该被其他事务所影响,各并发事务之间数据库是独立的。
4.持久性:一个事务被提交后,它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有影响。
3). 幻读 :
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。
众所周知,Mysql在InnoDB下有四种隔离级别:
未提交读(Read Uncommitted)
提交后读(Read Committed)
可重复读(Repeatable Read)
串行化(Serializable)
其中可重复读(RR)可以避免脏读( a事务读到b事务回滚前的数据)以及可不重复读( a事务在b事务修改提交的前后,两次分别读到的数据不一致)。但是对于幻读(a事务在b事务insert提交前后,两次分别读到的数据不一致),却存在争议。
下面我们来做一个试验:
对于下面这张简单的数据表
id num
1 11
2 22
3 33
我们开启a、b两个事务
a事务 b事务
begin begin
select * from tb ----
---- insert into tb (id,num)values(4,44)
---- commit
select * from tb ----
commit
试验结果:a事务的两次select查询到的结果相同,在后一次查询中没有返回新插入id=4的那条记录。
据此,很多人判断说RR隔离级别下“不存在”幻读。
但果真如此吗?----
出现上面的试验结果,是因为在RR隔离级别事务下,Mysql会对前一次select的结果快照。所以第二次select其实是快照读(这也正是RR隔离级别下能够避免不可重复读的策略)。
如果我们把试验条件稍作修改,同样开启a、b两个事务:
a事务 b事务
begin begin
select * from tb ----
---- insert into tb (id,num)values(5,55)
---- commit
update tb set num=num+1 ---- #此处a事务做一次修改操作
select * from tb ----
commit
试验结果:在a事务的第二次select中出现了b事务新插入的id=5的记录。
由于做了update操作,之前的快照失效了,所以说RR隔离级别下的快照策略并没能真正避免幻读。
ps. 假如给第二次的select查询上锁(无论是共享锁还是排它锁),也会得到同样的结果,都会令快照失效。
幻读是指:在一个事务中,读取到了其他已经提交的事务插入的数据行。
MySQL在解决脏读、不可重复的读时候,使用了MVCC一致性视图,同时配合行锁来解决。
至于幻读的解决方式,MySQL引入了临键锁,通过间隙锁可以避免在两个行之间插入数据,从而避免了一个事务在读取的过程中,读取到其他事务插入的数据行。
学习msyql隔离级别,事务,行排它锁,行共享锁,乐观锁,悲观锁即可