各位老铁们好,相信很多人对mysql隔离级别为什么设置为可重复读都不是特别的了解,因此呢,今天就来为大家分享下关于mysql隔离级别为什么设置为可重复读以及MySQL事务隔离级别的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
MySQL的可重复读级别能解决幻读吗
现在的主流数据库都使用MVCC,用了之后的RR隔离级别是不会出现幻读的。
不同的资料讲的RR是199X年的ANSISQL标准,但现实的数据库不一定符合标准(事实上,没有幻读是更好的事情)。
mysql默认存储引擎的命令
MySQL默认存储引擎为InnoDB,可以通过使用命令SHOWVARIABLESLIKE'storage_engine';
一、InnoDB存储引擎
1.InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID)
(MyISAM:不支持事务;只支持表级锁)
事务的ACID属性:即原子性、一致性、隔离性、持久性
a.原子性:原子性也就是说这组语句要么全部执行,要么全部不执行,如果事务执行到一半出现错误,数据库就要回滚到事务开始执行的地方。
实现:主要是基于MySQ日志系统的redo和undo机制。事务是一组SQL语句,里面有选择,查询、删除等功能。每条语句执行会有一个节点。例如,删除语句执行后,在事务中有个记录保存下来,这个记录中储存了我们什么时候做了什么事。如果出错了,就会回滚到原来的位置,redo里面已经存储了我做过什么事了,然后逆向执行一遍就可以了。
b.一致性:事务开始前和结束后,数据库的完整性约束没有被破坏。(eg:比如A向B转账,不可能A扣了钱,B却没有收到)
c.隔离性:同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰;
如果不考虑隔离性则会出现几个问题。
i、脏读:是指在一个事务处理过程里读取了另一个未提交的事务中的数据(当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致);(读取了另一个事务未提交的脏数据)
ii、不可重复读:在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了;(读取了前一个事务提交的数据,查询的都是同一个数据项。
iii、幻读:是事务非独立执行时发生的一种现象(eg:事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样);(读取了前一个事务提交的数据,针对一批数据整体)
d.持久性:事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚
2.InnoDB是mySQL默认的存储引擎,默认的隔离级别是RR,并且在RR的隔离级别下更近一步,通过多版本并发控制(MVCC)解决不可重复读问题,加上间隙锁(也就是并发控制)解决幻读问题。因此InnoDB的RR隔离级别其实实现了串行化级别的效果,而保留了比较好的并发性能。
不可重复读会导致什么问题
不可重复读可以这样理解:
有一个大事务,要执行很长时间;另外有一堆小事务,很快就执行完成。
大事务来回查一个数据。
一堆小事务串行(假设的,方便理解,禁止套娃)改这个数据,改完之后提交成功。
大事务虽然读到的也是小事务提交之后的内容,但是这个数据经常被小事务改来改去。
想避免不可重复读,可以给加共享锁(即读锁),加了共享锁之后,任何事务就不得加排他锁(即写锁)了,这样就完美解决了不可重复读的问题。
设置共享读锁也就是隔离级别提高到REPETABLE_READ可重读,这也是MySQL的默认隔离级别。
数据库哪个隔离级别可以实现脏读
对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:?脏读:对于两个事物T1,T2,T1读取了已经被T2更新但还没有被提交的字段.之后,若T2回滚,T1读取的内容就是临时且无效的.?不可重复读:对于两个事物T1,T2,T1读取了一个字段,然后T2更新了该字段.之后,T1再次读取同一个字段,值就不同了.?幻读:对于两个事物T1,T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行.之后,如果T1再次读取同一个表,就会多出几行.数据库事务的隔离性:数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题.一个事务与其他事务隔离的程度称为隔离级别.数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱数据库提供了4中隔离级别:隔离级别描述READUNCOMMITTED(读未提交数据)允许事务读取未被其他事务提交的变更,脏读、不可重复读和幻读的问题都会出现READCOMMITED(读已提交数据)只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍然会出现REPEATABLEREAD(可重复读)确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但幻读的问题依然存在SERIALIZABLE(串行化)确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可以避免,但性能十分低Oracle支持的2种事务隔离级别:READCOMMITED,SERIALIZABLE.Oracle默认的事务隔离级别为:READCOMMITEDMysql支持4中事务隔离级别.Mysql默认的事务隔离级别为:REPEATABLEREAD
mysql 的隔离是什么
mysql的隔离就是指,SQL标准定义了四种隔离级别,用来限定事务内外的哪些改变是可见的,哪些是不可见的。
譬如,读取未提交的数据【ReadUncommitted】在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。
还有,读取提交的内容【ReadCommitted】该隔离级别是大多数数据库的默认的隔离级别(不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别也支持不可重复读,即同一个select可能得到不同的结果。等等
好了,文章到此结束,希望可以帮助到大家。