大家好,又见面了,我是你们的朋友全栈君。
之前,我们有讲过数据库的索引,链接为 数据库索引详解 今天,我们将讲解数据库的隔离级别。
一、隔离级别的种类与分别可以解决的问题:
事务的隔离级别分为4个,即 读未提交(read uncommitted)、读已提交(read committed)、可重复读(Repeatable read)、可串行化(Serializable)
oracle默认的隔离级别为 读已提交。mysql的默认隔离级别为 可重复读。
其中可以解决的问题如下表:
简单来说:
脏读即为session A读取到了session B中未提交的数据
不可重复读即为session A读取到了session B提交的数据,即前后session A读取的数据不一致
幻读即为session A读取到了session B insert的数据。
二、隔离级别的设置与查询:
1、设置隔离级别:
设置隔离级别分为设置全局的隔离级别与设置当前的隔离级别
全局设置,已存在的session不会生效,以后的新session会生效(以读未提交举例):
set global transaction isolation level read uncommitted;
单独设置当前连接:
set session transaction isolation level read uncommitted;
2 、查看当前隔离级别:
select @tx_isolation;
三、事务隔离级别的测试:
有一个goods表,里面有id、count(商品数量)、brandId(品牌id)
CREATE TABLE `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`count` int(11) DEFAULT '0',
`brandId` int(11) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_brandId` (`brandId`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf-8;
1、脏读(设置隔离级别为读未提交):
脏读为读到其它事务未提交的数据:
A | B |
select * from goods where id = 1; 返回1 |
|
update goods set count = 2 where id = 1; | |
select * from goods where id = 1; 返回2 |
|
commit; |
2、不可重复读(设置隔离级别为 读已提交)
不可重复读为读到其它数据已提交的数据,即前后查询数据不一致
A | B |
select * from goods where id = 1; 返回1 |
|
update goods set count = 2 where id = 1; | |
select * from goods where id = 1; 返回1 |
|
commit; | |
select * from goods where id = 1; 返回2 |
3、幻读(设置隔离级别为 可重复读):
幻读为读到别人已提交的写入数据库的数据。
幻读与不可重复读的区别为幻读为读到新插入的数据(insert),而不可重复读主要是更改与删除(update、delete)。
即不可重复读前后被其它session update、delete的数据没有问题,不会有变化,但是其它session insert的可能有变化。
A | B |
select * from goods where brandId = 1; 返回有id为1,2的两条 |
|
insert into goods (count,brandId) values (3, 1); | |
commit; | |
select * from goods where brandId = 1; 返回有id为1,2,3的三条 |
当隔离级别为 可串行化 的时候则不会出现上述问题。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/141226.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...