数据库四种隔离级别

首先用通俗的语言介绍以下事务的特性(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 |
+------------------+

 

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 彻底弄懂LSH之simHash算法[通俗易懂]

    彻底弄懂LSH之simHash算法[通俗易懂]马克·吐温曾经说过,所谓经典小说,就是指很多人希望读过,但很少人真正花时间去读的小说。这种说法同样适用于“经典”的计算机书籍。最近一直在看LSH,不过由于matlab基础比较差,一直没搞懂

    2022年8月5日
    4
  • plt.savefig()的用法以及保存路径

    plt.savefig()的用法以及保存路径图像有时候比数据更能满足人们的视觉需求pytorch下保存图像有很多种方法,但是这些基本上都是基于图像处理的,将图像的像素指定一定的维度,具体可见以下博客:Pytorch中保存图片的方式_造未来-CSDN博客_pytorch保存图片主要是写一些函数来保存图片;另外,pytorch中有很多可以直接保存图片的语句如save_image(fake_images,’./img/fake_images-{}.png’.format(epoch+1))此语句同样需要转化像素。.

    2022年6月22日
    445
  • 高级PHP开发:利用PHPEMS搭建在线考试平台

    高级PHP开发:利用PHPEMS搭建在线考试平台

    2021年10月16日
    36
  • 最简单的三极管音频放大电路

    最简单的三极管音频放大电路最简单的三极管音频放大电路最简单的三极管音频放大电路 调节R1大小,使在最大输出时信号不失真即可,减小R可输出更大的功率。如果有万用表,可将C极电压调为电源电压的1/2左右。        图一固定偏置,电源电压对偏置电流影响很大 基本的共发射极电路   require.async([‘wkcommon:widget/ui

    2022年6月5日
    82
  • 模糊PID算法及其MATLAB仿真(1)

    模糊PID算法及其MATLAB仿真(1)目录1、PID控制2、模糊控制3、模糊PID简介4、模糊自整定PID的理论内容(重点内容)4.1基本原理4.2模糊子集及其论域的确定4.3模糊规则的建立4.4模糊推理1、PID控制PID控制是及其普遍的控制方法,主要分为位置式PID和增量式PID,主要方程大家可以查看其他资料,这里就不作详细的解释了,另外还需要了解阶跃响应曲线上面的超调…

    2022年6月3日
    43
  • JVM 关于静态变量存储位置的问题[通俗易懂]

    JVM 关于静态变量存储位置的问题[通俗易懂]形如staticList<>a=newList<>();我知道a指向的List的对象肯定是在堆内存中,但a本身它存放在哪儿?java8后,永久代已经被移除,被称为“元数据区”的区域所取代。类的元数据放入nativememory,字符串池和类的静态变量放入java堆中,静态变量初始化就在堆,a就在堆中。…

    2022年6月6日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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