数据库四种隔离级别

首先用通俗的语言介绍以下事务的特性(ACID): 原子性(Atomicity):原子性是指一个事务中的操作,要么全部成功,要么全部失败,如果失败,就回滚到事务开始前的状态。 一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。那转账举栗子,A账户和B账户之间相互转账,无论如何操作…

大家好,又见面了,我是你们的朋友全栈君。

首先用通俗的语言介绍以下事务的特性(ACID):

  1. 原子性(Atomicity):原子性是指一个事务中的操作,要么全部成功,要么全部失败,如果失败,就回滚到事务开始前的状态。

  2. 一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。那转账举栗子,A账户和B账户之间相互转账,无论如何操作,A、B账户的总金额都必须是不变的。

  3. 隔离性(Isolation):隔离性是当多个用户 并发的 访问数据库时,如果操作同一张表,数据库则为每一个用户都开启一个事务,且事务之间互不干扰,也就是说事务之间的并发是隔离的。再举个栗子,现有两个并发的事务T1和T2,T1要么在T2开始前执行,要么在T2结束后执行,如果T1先执行,那T2就在T1结束后在执行。关于数据的隔离性级别,将在后文讲到。

  4. 持久性(Durability):持久性就是指如果事务一旦被提交,数据库中数据的改变就是永久性的,即使断电或者宕机的情况下,也不会丢失提交的事务操作。

 

什么是事务的隔离性(Isolation)呢?

隔离性是指,多个用户的并发事务访问同一个数据库时,一个用户的事务不应该被其他用户的事务干扰,多个并发事务之间要相互隔离。

 

如果不考虑隔离性,会发生什么事呢?

    1.脏读:

脏读是指一个事务在处理数据的过程中,读取到另一个为提交事务的数据。

--原数据
--id    name
--1     lisi

--事务1
START TRANSACTION;
updata t_table set name = 'wangwu' where id = 1;    --此时事务2查询id = 1
ROLLBACK;

--事务2
select * from t_table where id = 1;        --查询到 id = 1, name = 'wangwu'

事务1并没有提交,name 还是 lisi,但是事务2却读到了 name = wangwu,这就是脏读。如果换成A给B转账,B查询到了没有提交的事务,认为已经收到A转过来的钱,那岂不是很恐怖。

不过在实际开发中,应该很少有人会犯这样的低级错误。

    2.不可重复读:

不可重复读是指对于数据库中的某个数据,一个事务范围内的多次查询却返回了不同的结果,这是由于在查询过程中,数据被另外一个事务修改并提交了。

--原数据
--id    name
--1     lisi

--事务1
select * from t_table where id = 1;    -- 查询到 id = 1, name = list, 事务2在此时提交
select * from t_table where id = 1;    -- 查询到 id = 1, name = wangwu

--事务2
start transaction;
update t_table set name = 'wangwu' where id = 1;
COMMIT;

不可重复读和脏读的区别是,脏读读取到的是一个未提交的数据,而不可重复读读取到的是前一个事务提交的数据。

而不可重复读在一些情况也并不影响数据的正确性,比如需要多次查询的数据也是要以最后一次查询到的数据为主。

    3.幻读

幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

--原数据
--id    name
--1     lisi

--事务1
select * from t_table where id = 2;    --返回NULL,此时事务2提交
select * from t_table where id = 2;    --返回id = 2, name = wangwu


--事务2
insert into t_table values(2,'wangwu');
COMMIT;

不可重复读和幻读是初学者不易分清的概念,我也是看了详细的解读才明白的,总的来说,解决不可重复读的方法是 锁行,解决幻读的方式是 锁表

 

四种隔离级别解决了上述问题

    1.读未提交(Read uncommitted):

这种事务隔离级别下,select语句不加锁。

此时,可能读取到不一致的数据,即“读脏 ”。这是并发最高,一致性最差的隔离级别。

    2.读已提交(Read committed):

可避免 脏读 的发生。

在互联网大数据量,高并发量的场景下,几乎 不会使用 上述两种隔离级别。

    3.可重复读(Repeatable read):

MySql默认隔离级别。

可避免 脏读 不可重复读 的发生。

    4.串行化(Serializable ):

可避免 脏读、不可重复读、幻读 的发生。

 

以上四种隔离级别最高的是 Serializable 级别,最低的是 Read uncommitted 级别,当然级别越高,执行效率就越低。像 Serializable 这样的级别,就是以 锁表 的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读) 

  在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读) ;而在 Oracle数据库 中,只支持Serializable (串行化) 级别和 Read committed (读已提交) 这两种级别,其中默认的为 Read committed(读已提交) 级别。

 

查询和设置数据库的隔离级别:

select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
set tx_isolation='隔离级别';    --read-uncommitted    read-committed    repeatable-read    serializable
set tx_isolation='read-uncommitted';

select @@tx_isolation;
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/124588.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Hibernate Criterion

    Hibernate Criterion

  • 分子模拟软件amber_【免费】指南针模拟计算课堂第五期:邂逅分子模拟「建议收藏」

    分子模拟软件amber_【免费】指南针模拟计算课堂第五期:邂逅分子模拟「建议收藏」不知不觉,在大家的陪伴和参与下,科学指南针的免费模拟计算线上课堂,将在本周六(12.7号)来到最后一期啦!一前四期的内容,我们分别讲了计算化学的整体情况、分类的量子化学和第一性原理的基本知识普及和操作演示。错过了前四期的小伙伴,也不要失望,每期课程都有视频,文章末尾有获取前四期视频的方式,欢迎领取。二第五期的课程,我们将带大家再了解下分子模拟的相关内容。本期课程包括分子动力学和力场的一些…

  • sql服务器系统时间格式,SQL Server 日期格式和日期操做

    sql服务器系统时间格式,SQL Server 日期格式和日期操做SQLServer发展至今,关于日期的格式的控制方法,有传统的方法,好比CONVERT(),也有比较便利的新方法,好比FORMAT();一样,关于日期的操做函数,也分为传统方法:DATEADD()等,也有便利的新方法:EOMonth()等。sql一,日期的格式化格式化是指把日期类型(Date)、日期和时间类型转化为字符类型,一般使用CONVERT()和FORMAT()函数。express1,传统…

    2022年10月19日
  • Mac — MySql配置环境变量

    Mac — MySql配置环境变量全网最详细的Mac–MySql环境配置变量,包教会????,不信你就来看

  • 那是什么进程 —— jusched.exe是什么? 它为何运行?「建议收藏」

    那是什么进程 —— jusched.exe是什么? 它为何运行?「建议收藏」       如果你曾经看到任务管理器里有个jusched.exe并很疑惑它究竟是什么,如果你将它关了,那么你很幸运,因为这个进程是负责Java更新的程序,它每个月检查一次Java是否有新的更新,并且一直在那儿浪费内存.       在Windows系统中有个调度任务的功能,由于这个进程每个月才被调度一次,显而易见不是什么重要更新,我不能理解这个进程为什么需要浪费我的内…

    2022年10月23日
  • 机器学习模型中的损失函数loss function

    机器学习模型中的损失函数loss functionimportmatplotlib.pyplotaspltimportnumpyasnpxmin,xmax=-4,4xx=np.linspace(xmin,xmax,100)plt.plot([xmin,0,0,xmax],[1,1,0,0],’k-‘,label=”Zero-oneloss”)plt.plot(xx,np.where(x

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号