数据库事务的四大特性与隔离级别及测试

2023-05-16

四大特性

⑴ 原子性(Atomicity)

  原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

⑵ 一致性(Consistency)

  一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

  拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

⑶ 隔离性(Isolation)

  隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

  即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

  关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。

⑷ 持久性(Durability)

  持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

  例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。


隔离级别

以上介绍完事务的四大特性(简称ACID),现在重点来说明下事务的隔离性,当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:

1,脏读

  脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

例:
创建一个表

INSERT INTO `kedb`.`test_table`
(`id`,
`age`)
VALUES
(<{id: }>,
<{age: }>);

插入一个数据:

INSERT INTO `kedb`.`test_table`
(
`age`)
VALUES
(
5);

这里写图片描述

数据库隔离级别操作:

-- 获取全局隔离级别  
SELECT @@global.tx_isolation;  
--获取会话隔离级别  
SELECT @@tx_isolation; 

--全局隔离级别设置  
SET GLOBAL TRANSACTION ISOLATION LEVEL [  
           READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE];  
--会话隔离级别设置  
SET SESSION TRANSACTION ISOLATION LEVEL [  
            READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE];  

查看数据库的隔离级别

select @@global.tx_isolation;

这里写图片描述

修改级别为read uncommitted;

set gloabal transaction isolation level read uncommitted;

再查看:

select @@global.tx_isolation;

这里写图片描述

这里写图片描述

在终端A开启一个修改事务:
这里写图片描述
但是还未提交

这时开启另一个终端B,查询:
这里写图片描述

终端A进行回滚事务:
这里写图片描述

现在查询:
这里写图片描述

(B可以认为是客户端,A可认为是服务端)
可以发现A的事务还未提交时,B就去获取了,B获取的是个当前状态的,但B并不知道A的事务是否已经提交。这样如果A事务进行回滚数据就不会发生改变,而B却得到了一个改变后的数据,这就是脏读。

那么怎么解决这一问题?
只要将隔离级别设为read uncommitted更高的级别就可以了
这里写图片描述
现在再次模拟:
这里写图片描述
可以发现B这时就不会再因为A事务没提交而出现脏读了。

2,不可重复读

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

例如:
事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发生了不可重复读。

再举个例子:
事务1:查询有双人床房间。99号房间,有双人床。
事务2:将99号房间,改成单人床房间。
事务1:再次执行查询,请求所有双人床房间列表,99号房间不再列表中了。也就是说,事务1,可以看到其他事务所做的修改。
在不可重复读,里面,可以看到其他事务所做的修改,而导致2次的查询结果不再一样了。这里的修改,是提交过的。也可以是没有提交的,这种情况同时也是脏读。
如果,数据库系统的隔离级别。允许,不可重复读。那么你启动一个事务,并做一个select查询操作。查询到的数据,就有可能,和你第2次,3次…n次,查询到的数据不一样。一般情况下,你只会做一次,select查询,并以这一次的查询数据,作为后续计算的基础。因为允许出现,不可重复读。那么任何时候,查询到的数据,都有可能被其他事务更新,查询的结果将是不确定的。

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

模拟:
再次之前已经将级别设为read committed;
这里写图片描述
从以上可以发现事务A在修改时,这时B开始读取,读取的是A修改之前的数据。没有发生脏读。

现在A提交事务,B再次查询:
这里写图片描述
这时B查询到的结果就不是第一次查询的结果了,所以出现了不可重复读。

可能你会觉得这样也很符合逻辑呀,注意这是异步执行的,而且A,B同时执行,可B却读取了不同的数据,主要原因就是异步。如果改成同步,A事务再修改的时候,B只能进行等待,当A事务结束后B再执行,这样B就能得到正确的数据了。

那么怎么解决这问题?
可以想象就是同步了,在A执行这个事务的时候,B事务就必须进入等待,在A事务执行完后B再进行执行。
以上是分析,在InnoDB中可以设置隔离级别为repeatable read解决不可重复读的问题。

repeatable read
读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
避免了不可重复读取和脏读,但是有时可能出现幻读。这可以通过“共享读锁”和“排他写锁”实现。

3,虚读(幻读)

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

这是最高的隔离级别,它通过强制事务排序使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。只要操作产生了锁,就不允许其他事务读取和修改!

在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:
这里写图片描述

REPEATABLE READ 是MySQL的默认事务隔离级别

REPEATABLE READ 这是MySQL的默认事务隔离级别,能确保事务在并发读取数据时会看到同样的数据行,解决了READ-COMMITTED隔离级别下的不可重复读问题。mysql的InnoDB存储引擎通过多版本并发控制(Multi_Version Concurrency Control, MVCC)机制来解决该问题。在该机制下,事务每开启一个实例,都会分配一个版本号给它,如果读取的数据行正在被其它事务执行DELETE或UPDATE操作(即该行上有排他锁),这时该事物的读取操作不会等待行上的锁释放,而是根据版本号去读取行的快照数据(记录在undo log中),这样,事务中的查询操作返回的都是同一版本下的数据,解决了不可重复读问题。其原理如下图所示:

这里写图片描述

 缺陷:虽然该隔离级别下解决了不可重复读问题,但理论上会导致另一个问题:幻读(Phantom Read)。正如上面所讲,一个事务在执行过程中,另一个事物对已有数据行的更改,MVCC机制可保障该事物读取到的原有数据行的内容相同,但并不能阻止另一个事务插入新的数据行,这就会导致该事物中凭空多出数据行,像出现了幻读一样,这便是幻读问题。

而解决幻读问题,就得使用serializable级别了。
SERIALIZABLE 这是事务的最高隔离级别,通过强制事务排序,使之不可能相互冲突,就是在每个读的数据行加上共享锁来实现。在该隔离级别下,可以解决前面出现的脏读、不可重复读和幻读问题,但也会导致大量的超时和锁竞争现象,一般不推荐使用。


参考:http://www.cnblogs.com/JohnABC/p/3521061.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据库事务的四大特性与隔离级别及测试 的相关文章

  • Linux学习笔记三-Shell编程

    bash脚本编写 编写bash脚本程序有两种方式 1 可以输入一系列命令让bash交互地执行它们 xff0c 2 也可以把这些命令保存到一个文本文件中 xff0c 然后将该文件作为一个程序来调用 在执行shell命令时多个命令可以在一个命令
  • 二叉搜索树详解链式与数组式实现

    前沿 xff1a 首先让我们认识下什么是二叉搜索树 xff0c 二叉搜索树是十分高效的一种搜索算法 xff0c 定义为 xff1a 它的每个节点都有以下性质 xff08 在左右子树都不为空的情况下 xff09 自己本身的权值比它的左子树大
  • Linux学习笔记四-Shell中[],(())

    的使用 的返回值 xff1a 0 代表真1 代表假 中可用的比较运算符只有 61 61 和 61 xff0c 两者都是用于字符串比较的 xff0c 不可用于整数比较 xff0c 整数比较只能使用 eq xff0c gt这种形式 无论是字符串
  • Java集合源码学习(一)集合框架

    原文地址 xff1a https yq aliyun com articles 38397 spm 61 5176 8091938 0 0 fRUCzz 集合框架 Java集合框架包含了大部分Java开发中用到的数据结构 xff0c 主要包
  • Java集合源码学习(二)ArrayList分析

    原文地址 xff1a https yq aliyun com articles 38407 spm 61 5176 8091938 0 0 3G9cay 关于ArrayList ArrayList直接继承AbstractList xff0c
  • Java集合源码学习(三)LinkedList分析

    原文地址 xff1a https yq aliyun com articles 38408 spm 61 5176 8091938 0 0 tjeCwH 前言 前面学习了ArrayList的源码 xff0c 数组是顺序存储结构 xff0c
  • Java集合源码学习(四)HashMap分析

    原文地址 xff1a https yq aliyun com articles 38410 spm 61 5176 8091938 0 0 01LA3v 摘要 ArrayList LinkedList和HashMap的源码是一起看的 xff
  • Java类的加载顺序及生命周期原理解析

    摘要 经常看到java面试题static 构造函数等混合执行 问会输出什么 xff0c 这里针对类的加载及类的生命周期进行原理的解析 xff0c 就能很快明白了 java类的加载顺序 简单的说 xff0c 首先要知道Java虚拟机对clas
  • 牛客网-贪心-裁减网格纸

    https www nowcoder com questionTerminal 65865c6644154bb4acca764b1480ecbb orderByHotValue 61 1 amp questionTypes 61 00010
  • 牛客网-贪心-最大间隔

    https www nowcoder com questionTerminal 3a571cdc72264d76820396770a151f90 orderByHotValue 61 1 amp questionTypes 61 00010
  • Ubuntu 执行属性为executable (application/x-executable)的文件

    ubuntu14 04 LTS下执行属性为executable application x executable 的文件的方法 xff1a 1 chmod 43 x filename 2 filename 就可以执行了 xff01 xff0
  • 牛客网-贪心-扫描透镜

    https www nowcoder com questionTerminal 6a219d196df44d3abd82fbadb1a62c3f orderByHotValue 61 1 amp questionTypes 61 00010
  • TCP三次握手与四次握手

    HTTP工作流程 当我们从浏览器输入一个url xff0c Http的工作流程如下图所示 xff1a DNS解析流程请看DNS域名解析过程这篇文章 现在来讲TCP三次握手 TCP三次握手 什么是TCP TCP是主机对主机层的传输控制协议 x
  • JAVA题目汇总

    什么是Java虚拟机 xff1f 为什么Java被称作是 平台无关的编程语言 xff1f Java虚拟机是一个可以执行Java字节码的虚拟机进程 Java源文件被编译成能被Java虚拟机执行的字节码文件 Java被设计成允许应用程序可以运行
  • 二维数组中的查找

    时间限制 xff1a 1秒 空间限制 xff1a 32768K 热度指数 xff1a 343751 本题知识点 xff1a 查找 算法知识视频讲解 题目描述 在一个二维数组中 xff0c 每一行都按照从左到右递增的顺序排序 xff0c 每一
  • 替换空格

    时间限制 xff1a 1秒 空间限制 xff1a 32768K 热度指数 xff1a 307877 本题知识点 xff1a 字符串 算法知识视频讲解 题目描述 请实现一个函数 xff0c 将一个字符串中的空格替换成 20 例如 xff0c
  • 从尾到头打印链表(链表反转)

    时间限制 xff1a 1秒 空间限制 xff1a 32768K 热度指数 xff1a 265674 本题知识点 xff1a 链表 算法知识视频讲解 题目描述 输入一个链表 xff0c 从尾到头打印链表每个节点的值 笔记收藏纠错 span c
  • 重建二叉树

    时间限制 xff1a 1秒 空间限制 xff1a 32768K 热度指数 xff1a 177198 算法知识视频讲解 题目描述 输入某二叉树的前序遍历和中序遍历的结果 xff0c 请重建出该二叉树 假设输入的前序遍历和中序遍历的结果中都不含
  • 用两个栈实现队列

    时间限制 xff1a 1秒 空间限制 xff1a 32768K 热度指数 xff1a 118150 本题知识点 xff1a 队列 栈 算法知识视频讲解 题目描述 用两个栈来实现一个队列 xff0c 完成队列的Push和Pop操作 队列中的元

随机推荐

  • 旋转数组的最小数字

    时间限制 xff1a 3秒 空间限制 xff1a 32768K 热度指数 xff1a 162501 本题知识点 xff1a 查找 算法知识视频讲解 题目描述 把一个数组最开始的若干个元素搬到数组的末尾 xff0c 我们称之为数组的旋转 输入
  • 变态的台阶

    时间限制 xff1a 1秒 空间限制 xff1a 32768K 热度指数 xff1a 98625 算法知识视频讲解 题目描述 一只青蛙一次可以跳上1级台阶 xff0c 也可以跳上2级 它也可以跳上n级 求该青蛙跳上一个n级的台阶总共有多少种
  • 解决xterm显示远程窗口出现“Can't open display: localhost:11.0”的问题

    参考 xff1a http unix stackexchange com questions 117159 cannot start xterm over ssh after several successes 问题描述 xff1a 远程调
  • 数值的整数次方

    时间限制 xff1a 1秒 空间限制 xff1a 32768K 热度指数 xff1a 117073 算法知识视频讲解 题目描述 给定一个double类型的浮点数base和int类型的整数exponent 求base的exponent次方 笔
  • 机器人走方格I

    链接 xff1a https www nowcoder com questionTerminal e8bb8e68434e42acbcdff0341f2a32c5 orderByHotValue 61 1 amp mutiTagIds 61
  • 年终奖

    链接 xff1a https www nowcoder com questionTerminal 72a99e28381a407991f2c96d8cb238ab orderByHotValue 61 1 amp mutiTagIds 61
  • 最近公共祖先

    链接 xff1a https www nowcoder com questionTerminal 70e00e490b454006976c1fdf47f155d9 orderByHotValue 61 1 amp mutiTagIds 61
  • 直方图内最大矩形

    有一个直方图 xff0c 用一个整数数组表示 xff0c 其中每列的宽度为1 xff0c 求所给直方图包含的最大矩形面积 比如 xff0c 对于直方图 2 7 9 4 它所包含的最大矩形的面积为14 即 7 9 包涵的7x2的矩形 给定一个
  • 罪犯转移

    题目描述 C市现在要转移一批罪犯到D市 xff0c C市有n名罪犯 xff0c 按照入狱时间有顺序 xff0c 另外每个罪犯有一个罪行值 xff0c 值越大罪越重 现在为了方便管理 xff0c 市长决定转移入狱时间连续的c名犯人 xff0c
  • 路灯

    一条长l的笔直的街道上有n个路灯 xff0c 若这条街的起点为0 xff0c 终点为l xff0c 第i个路灯坐标为a i xff0c 每盏灯可以覆盖到的最远距离为d xff0c 为了照明需求 xff0c 所有灯的灯光必须覆盖整条街 xff
  • 哈希表

    哈希表 概念 哈希表 Hash Table 也叫散列表 xff0c 是根据关键码值 xff08 Key Value xff09 而直接进行访问的数据结构 它通过把关键码值映射到哈希表中的一个位置来访问记录 xff0c 以加快查找的速度 这个
  • 哈夫曼树

    概念 哈夫曼树是一种带权路径长度最短的二叉树 xff0c 也称为最优二叉树 下面用一幅图来说明 它们的带权路径长度分别为 xff1a 图a xff1a WPL 61 5 2 43 7 2 43 2 2 43 13 2 61 54 图b xf
  • tomcat配置问题导致IDEA报错

    总结一下遇到的问题 xff1a 1 tomcat的startup闪退 xff1a 解决办法 xff1a 1 环境变量配置不能错 2 端口错误这个是新手特别超级容易犯的错误 xff0c 在装tomcat的时候经常一顿next安装了 xff0c
  • 递归转动态规划套路总结

    来自左神的教导总结 1 确定递归函数意义 2 确定大小范围 xff0c 设计表 3 确定递归终止状态 xff0c 填表边界 xff08 自底向上时 xff1a 从结尾填表 xff1b 自顶向下时 xff0c 跟踪递归流程填表 xff09 例
  • 最长公共子串

    对于两个字符串 xff0c 请设计一个时间复杂度为O m n 的算法 这里的m和n为两串的长度 xff0c 求出两串的最长公共子串的长度 这里的最长公共子串的定义为两个序列U1 U2 Un和V1 V2 Vn xff0c 其中Ui 43 1
  • JAVA虚拟机加载类到运行过程总结

    理解Java跨平台运行原理 java之所以可以跨平台是因为编译器并没有把源码文件直接编译成机器指令 xff0c 而是编译成java虚拟机可以识别和运行的字节码文件 java gt class 而字节码文件是一种无关平台的中间编译结果 xff
  • 硬币表示

    有数量不限的硬币 xff0c 币值为25分 10分 5分和1分 xff0c 请编写代码计算n分有几种表示法 给定一个int n xff0c 请返回n分有几种表示法 保证n小于等于100000 xff0c 为了防止溢出 xff0c 请将答案M
  • 最长公共子序列

    我们有两个字符串m和n xff0c 如果它们的子串a和b内容相同 xff0c 则称a和b是m和n的公共子序列 子串中的字符不一定在原字符串中连续 例如字符串 abcfbc 和 abfcab xff0c 其中 abc 同时出现在两个字符串中
  • 完全二叉树的特点

    定义 完全二叉树是由满二叉树而引出来的 对于深度为K的 xff0c 有n个结点的二叉树 xff0c 当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树 一棵二叉树至多只有最下面的一层上的结点的度数可以小
  • 数据库事务的四大特性与隔离级别及测试

    四大特性 原子性 xff08 Atomicity xff09 原子性是指事务包含的所有操作要么全部成功 xff0c 要么全部失败回滚 xff0c 这和前面两篇博客介绍事务的功能是一样的概念 xff0c 因此事务的操作如果成功就必须要完全应用