数据库四种隔离级别

首先用通俗的语言介绍以下事务的特性(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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • iframe的高度自适应_div自适应高度

    iframe的高度自适应_div自适应高度Demo页面:主页面iframe_a.html,被包含页面iframe_b.htm和iframe_c.html下面开始讲:通过Google搜索iframe自适应高度,结果5W多条,搜索iframe高度自适应,结果2W多条。我翻了前面的几十条,刨去大量的转载,有那么三五篇是原创的。而这几篇原创里面,基本上只谈到如何自适应静的东西,就是没有考虑到JS操作DOM之后,如

    2022年10月12日
    6
  • 数据库分区及分区优点

    数据库分区及分区优点此文从以下几个方面来整理关于分区表的概念及操作:        1.表空间及分区表的概念        2.表分区的具体作用        3.表分区的优缺点        4.表分区的几种类型及操作方法        5.对表分区的维护性操作. (1.)表空间及分区表的概念 表空间:   是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中

    2022年6月5日
    42
  • 新浪云服务器使用流程[通俗易懂]

    新浪云服务器使用流程[通俗易懂]注册背景:当我们进行微信公众号开发的时候,需要使用一个服务器跟微信的服务器链接,如果在本地搭建服务器默认情况下,本地服务器是不能被外网链接的;这样就需要去解决这个问题,解决的方案又两种:方案一:

    2022年8月3日
    9
  • vs2010专业板产品密钥

    vs2010专业板产品密钥网上查找很多,大家都在使用这个,试过之后,可以。YCFHQ-9DWCY-DKV88-T2TMH-G7BHP

    2022年5月8日
    43
  • 查看Mysql锁情况

    查看Mysql锁情况#当前运行的所有事务select*frominformation_schema.innodb_trx;#当前出现的锁select*frominformation_schema.innodb_locks;#锁等待的对应关系select*frominformation_schema.innodb_lock_waits#查看下autocommit的值se…

    2022年6月1日
    35
  • Windows~~~在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password: YES) ,并修改MySQL密码

    Windows~~~在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password: YES) ,并修改MySQL密码适用于windows安装MySQL 对于出现拒绝访问root用户的解决方案 错误1045(28000):用户’root’@’localhost’(使用密码:YES)拒绝访问首先解析此英文:ERROR1045(28000):Accessdeniedforuser’root’@’localhost'(usingpassword:YES);解析的地方有…

    2022年6月13日
    31

发表回复

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

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