今天请了一天假去卓望公司面试,被问到数据库隔离机制的问题,真的没准备,平时的工做用到的也很少,数据库默认机制是啥也没怎么关心,回来看了点资料,打开mysql测试了一下,终于清楚了!总结一下可能被问到的问题:mysql
一、数据库有几种隔离级别:面试
答:四种,由低到高依次为sql
1)Read uncommitted(未受权读取、读未提交)、---各类好处:脏读、虚读(不可重复)、幻读数据库
2) Read committed(读提交)、 --- :虚读,幻读(发现了其它事务提交的记录)测试
3)Repeatable read(可重复读取)、 --- :无虚读幻读(不能发现其它事务已提交更新或插入的数据)spa
4) Serializable(序列化)。事务
脏读、虚(不可重复)读、幻读、这几种问题容易把问题搞混乱,脏读是指读取了其余事务没有提交的数据,另外两个是 没有读取到其余事务已经提交的变化。开发
其实彻底能够抛开这些中国人取的SB名词,直接从本意上理解: it
我理解以下:数据库有四种隔离级别:第一种 和 第四种 几乎只存在于实验室中吧,现实业务中根本不太可能用到,若是有用到的请告知我:很是感谢! 那就剩下两种隔离级别table
2) Read commited 仍是过去式,顾名思义,读到了已经提交的 。 说白了就是 ,事务一在执行过程当中,事务二迅速开始并提交,事务一在结束前能够查询到变化。
Oracle等大部分数据库,默认使用这种隔离级别 。(update\delete\insert等只要事务提交就能查到)
3)Repeatable read 同理,事务中的查询结果是可复现的,那就是事务结束前不能觉察到其它事务提交的变化。
Mysql 默认采用这种隔离级别。
到这里清楚了!!
真正在开发中,数据库定了,隔离机制也就肯定了
====================Mysql演示=============================================
-- 第1步 新建窗口,开启事务, START TRANSACTION; SELECT *,NOW() from t1 ; -- for UPDATE; SELECT sleep(10) ; --保证执行时间足以让其它事务执行完 SELECT t1.*,NOW() from t1 ; COMMIT;
-- 第二步,在前一段sql未结束事物前 在新的窗口执行第二个事务 START TRANSACTION; INSERT INTO t1 (name) VALUES ('b'); -- 测试幻读 SELECT t1.*,NOW() from t1 ; COMMIT;
-- 上图中顺序:左图执行-》右图执行-》右图查询结束-》左图查询结束,数据库中多了一条数据
-- 但左图中没有查询到
-- 第二步,在前一段sql未结束事物前 在新的窗口执行第二个事务 START TRANSACTION; -- 测试虚读 update t1 set t1.`name` = concat(t1.`name`,NOW()) WHERE t1.id = 1 ; SELECT t1.*,NOW() from t1 ; COMMIT;
-- 上图中顺序:左图执行-》右图执行-》右图查询结束-》左图查询结束,数据库中更新了一条数据
-- 左图中没有查询到,证实了mysql 默认使用可重复读 也就是虚读
Oracle默认的事务隔离级别是read commited,在此级别下,经过多版本的控制解决了幻读和幻读。
Mysql 显然没有,但能够经过在数据库中设置乐观锁字段或使用悲观锁来控制数据一致性