四种隔离级别
MySQL有四种隔离级别分别为读未提交(Read Uncommitted),读提交(Read Committed),可重复读 (Repeatable Read),串行化(Serializable)。隔离级别越高,数据的安全性越高不会出现幻读和脏读,但可并发性越低。所以在选择MySQL数据库隔离级别要在业务的并发性和安全性做权衡。
读未提交(Read Uncommitted)
读未提交在四个隔离级别中级别最低,指的一个事务能看到其他未提交事务的数据也叫脏读数据。我们举例说明: 创建表
create table `user_info`(
`id` bigint(20) NOT NULL PRIMARY KEY,
`name` varchar(11),
`age` int(11),
`phone` varchar(20),
KEY `key_name_age` (`name`,`age`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
设置隔离级别为读未提交(Read Uncommitted)
set global transaction isolation level read uncommitted;
插入一条测试数据
insert into user_info(`id`,`name`,`age`,`phone`)
values(1,'zhangsan',20,13888888888);
开启事务A修改测试数据
新起一个会话查询这条记录
我们发现事务A未提交但是可以查到这条记录已经被修改了,这种隔离级别在复杂操作业务不会使用,一般在没有事务的业务中使用。
读提交(Read Committed)
读提交指一个事务只能读取其他事务提交后的数据,但是会出现一个事务多次查询得到的结果不一样的情况即不可重复读现象。下面举例说明:
设置隔离级别为读未提交(Read Uncommitted)
set global transaction isolation level read committed;
插入一条测试数据
insert into user_info(`id`,`name`,`age`,`phone`)
values(2,'lisi',30,13111111111);
开启事务A更新数据
新起一个会话查询这条记录
可以看到情况跟读未提交不一样,还未提交的事务,其他事务是读不到的。
继续举例不可重复读现象:
开启事务A查询记录
新起一个会话修改这个条记录
继续用事务A查询这条记录
事务A第二次查询跟第一次查询的值不一样了,这就是不可重复读现象,这种现象其实没有多大的危害,只是违反了数据库ACID中的隔离性原则。
可重复读 (Repeatable Read)
可重复读包含了读提交中的特性同时也消除了不可重复读现象,在MySQL中是默认的隔离级别,但是未消除幻读现象。下面举例说明:
设置隔离级别为读未提交(Repeatable Read)
set global transaction isolation level repeatable read;
插入一条测试数据
insert into user_info(`id`,`name`,`age`,`phone`)
values(3,'wangwu',40,13222222222);
开启事务A查询记录
新起一个会话修改这个条记录
继续用事务A查询这条记录
事务A第二次查询跟第一次查询的值一样,说明已经消除了不可重复读现象。
下面继续举例幻读现象:
开启事务A查询记录查询所有数据
新起一个会话插入一条数据记录
继续用事务A查询修改此条记录
用事务A查询所有数据
事务A最后一次查询比第一次查询多了一条记录,发生了幻读现象,
串行化(Serializable)
串行化的隔离级别最高同时消除了幻读和脏读现象,但是可并发性最低。此隔离级别给读取的记录加了共享锁,导致修改和并发不能同时进行。下面举例说明:
set global transaction isolation level serializable;
开启事务A查询记录查询
新起一个会话查询此条数据记录
查询时会出现锁超时,这是因为事务查记录时会对查询的数据加共享锁,导致其他事务修改时出现阻塞现象。
总结
网上找张图片对以上做下总结