事务隔离级别总结
时间:2022-07-24
本文章向大家介绍事务隔离级别总结,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
事务隔离级别总结
一. ACID特性
事务(Transaction)是数据库系统中一系列操作的一个逻辑单元,所有操作要么全部成功要么全部失
败。 事务是区分文件存储系统与Nosql数据库重要特性之一,其存在的意义是为了保证即使在并发情况下也
能正确的执行CRUD操作。怎样才算是正确的呢?这时提出了事务需要保证的四个特性即ACID:
- A:原子性(Atomicity) 一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- C: 一致性(Consistency) 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- I:隔离性(Isolation) 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行 时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(read uncommitted)、读已提交(read committed)、可重复读(repeatable read)和串行化(serializable)。
- D:持久性(Durability) 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
二. 事务隔离级别
在高并发的情况下,要完全保证其ACID特性是非常困难的,除非把所有的事务串行化执行,但带来的负 面的影响将是性能大打折扣。很多时候我们有些业务对事务的要求是不一样的,所以数据库中设计了四 种隔离级别,供用户基于业务进行选择。这四种隔离级别分别是:
- 读未提交(read uncommitted)
- 读已提交(read committed)
- 可重复读(repeatable read)
- 串行化(serializable)
其中,Oracle默认的级别是read committed,而MySQL默认为repeatable read。
注:MySQL中查看、设置事务隔离级别:
#查看事务隔离级别
SELECT @@tx_isolation;
#设置隔离级别为read-uncommitted
set tx_isolation='read-uncommitted';
三. 常见的数据库事务的问题
- 脏读(Dirty Read) 指一个事务读取到另一事务未提交的更新数据。
- 不可重复读(NonRepeatable Read) 指在同一事务中,多次读取同一数据返回的结果有所不同。也就是说,后续读取可以读到另一事务已提交的更 新数据。相反, 可重复读在同一事务中多次读取数据时,能够保证所读数据一样,也就是后续读取不能读到另一事务已提交的更新数据。
- 幻读(Phantom Read) 指在同一个事务中,多次读取到的数据数量不一致。也就是说,后续读取可以读取到另一个事务删除或者新增的数据。 不可重复读与幻读在概念上容易混淆,其不同在于:不可重复读侧重的是另一个事务对数据的修改,是行级别的操作。而幻读侧重的是另一个事务对数据的新增或删除,是整个表级别的操作。
采用不同的事务隔离级别,可解决不同的问题,总结如下:
隔离级别 |
脏读 |
不可重复读 |
幻读 |
---|---|---|---|
read uncommitted |
不可解决 |
不可解决 |
不可解决 |
read committed |
可解决 |
不可解决 |
不可解决 |
repeatable read |
可解决 |
可解决 |
不可解决 |
serializable |
可解决 |
可解决 |
可解决 |
可以看到,隔离级别越高,事务的安全性就越高,但是对性能的影响也越大,实际应用中应根据不同业务场景选择不同的隔离级别。
四. 事务隔离级别演示
- 准备 表结构:
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`money` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
- 脏读 开启2个数据库session,session1执行
#设置为读未提交
set tx_isolation='read-uncommitted';
BEGIN;
insert INTO `account` (`name`,`money`) VALUES ('Kobe',100);
- 此时session1向数据库插入了一条数据,还未提交。 这时,在session2中读取数据:
#设置为读未提交
set tx_isolation='read-uncommitted';
SELECT * from `account`;
- 不可重复读 初始化数据:
insert INTO `account` (`name`,`money`) VALUES ('Kobe',100);
- 在session1中执行查询:
#设置为读已提交
set tx_isolation='read-committed';
BEGIN;
SELECT * from `account`;
# 其他操作
此时查询到表中的数据是{1,Kobe,100}。
这时session2更新了表中的数据
#设置为读已提交
set tx_isolation='read-committed';
UPDATE `account` SET money= money+100 where `id`=1;
- 这时再在session1的当前事务中执行查询:
SELECT * from `account`;
- 幻读 初始化数据:
insert INTO `account` (`name`,`money`) VALUES ('Kobe',);
#设置为可重复读
set tx_isolation='REPEATABLE-READ';
BEGIN;
SELECT * FROM `account`;
#设置为可重复读
set tx_isolation='REPEATABLE-READ';
insert INTO `account` (`name`,`money`) VALUES ('James',100);
- 每天学习一点儿算法--递归
- 每天学习一点儿算法--选择排序
- 5个实用的Linux命令行技巧
- Python中的小魔法(二)
- flink与Spark的对比分析
- Spark自定义累加器的实现
- 每天学习一点儿算法--二分查找
- IntelliJ IDEA两种keymap快捷键方案Mac OS X和Mac OS X 10.5+的区别
- Apache Avro是什么干什么用的(RPC/序列化)
- 萌新刷题(十二)二叉树的前序遍历
- 轻松掌握ES6中集合Set的用法
- 萌新刷题(十三)买卖股票的最佳时机
- 萌新刷题(十一)有效数字
- Hive性能优化统计每日IP CREATE TABLE ip_2014_12_29 AS SELECT COUNT(DISTINCT ip) AS IP FROM logdfs WHERE logda
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python第三十一课--递归(1.简单递归函数的定义和使用)
- python第三十一课--递归(2.遍历某个路径下面的所有内容)
- python第三十一课--递归(3.递归的弊端)
- python第三十二课——栈
- linux系统运维企业常见面试题集合(三)
- python第三十二课——队列
- python第三十四课——1.匿名函数的定义和使用
- python第三十四课——2.匿名函数配合容器函数的使用
- 专家专栏|使用agent2自定义插件采集通过MQTT协议发送的数据
- Linux系统双网卡绑定配置教程
- python第三十五课——生成器
- python第三十六课——1.可迭代对象
- Linux系统Shell编程——脚本编写思路与过程
- python第三十六课——2.迭代器对象
- python第三十七课——模块