首页 > 数据库 >MySQL 事务特性和事务隔离级别

MySQL 事务特性和事务隔离级别

时间:2023-01-15 11:02:46浏览次数:45  
标签:事务 隔离 isolation 提交 MySQL 级别


1. MySQL 事务的四大特性
2. MySQL 事务的并发问题
3. MySQL 事务的隔离级别

---------------------------------------------------------
1. MySQL 事务的四大特性

MySQL 事务具有四个特性:原子性、一致性、隔离性、持久性,这四个特性简称 ACID 特性

一、原子性(Atomicity ):一个事务是一个不可再分割的整体,要么全部成功,要么全部失败

事务在数据库中就是一个基本的工作单位,事务中包含的逻辑操作(SQL 语句),只有两种情况:成功和失败。事务的原子性其实指的就是这个逻辑操作过程具有原子性,不会出现有的逻辑操作成功,有的逻辑操作失败这种情况

二、一致性(Consistency ):一个事务可以让数据从一种一致状态切换到另一种一致性状态

举例说明:张三给李四转账 100 元,那么张三的余额应减少 100 元,李四的余额应增加 100 元,张三的余额减少和李四的余额增加这是两个逻辑操作具有一致性

三、隔离性(Isolution ):一个事务不受其他事务的影响,并且多个事务彼此隔离

一个事务内部的操作及使用的数据,对并发的其他事务是隔离的,并发执行的各个事务之间不会互相干扰

四、持久性(Durability ):一个事务一旦被提交,在数据库中的改变就是永久的,提交后就不能再回滚

一个事务被提交后,在数据库中的改变就是永久的,即使系统崩溃重新启动数据库数据也不会发生改变

2. MySQL 事务的并发问题


上面讲到了事务的隔离性,当有多个任务时,应当让多个事务同时执行,这就是事务的并发。既然事务存在并发执行,那必然存在两个事务操作同一个数据的冲突问题,那么我们来看一下会出现哪些问题

下面介绍脏读、不可重复读、幻读时会涉及到事务隔离级别,可先略过。按照提示设置事务隔离级别即可,本文后面会介绍事务隔离级别。测试这几个事务并发问题可以通过打开两个终端窗口进行测试

查看事务隔离级别



  1. ​select @@transaction_isolation;​

一、脏读

MySQL 事务特性和事务隔离级别_事务隔离级别

测试脏读: 将事务隔离级别修改为读未提交



  1. ​# READ-UNCOMMITTED 读未提交​
  2. ​set session transaction isolation level read uncommitted;​

现在有两个事务,分别是事务 A 和事务 B。在事务 A 中查询一条数据,查询结果中 score 的值是 80,然后事务 B 去修改这一条数据,将 score 的值改为 90,但是它没有提交,这时候事务 A 去查询这条数据,发现数据竟然发生了变化。

脏读: 在一个事务里面,由于其他事务修改了数据并且没有提交,而导致前后两次读取的数据不一致的情况,这种事务并发问题称之为 “脏读”

二、不可重复读

MySQL 事务特性和事务隔离级别_数据库_02

测试不可重复读: 将事务隔离级别修改为读已提交



  1. ​# READ-COMMITTED 读已提交​
  2. ​set session transaction isolation level read committed;​

同样是两个事务,事务 A 查询一条数据,事务 B 修改了这条数据,特别注意,这里事务 B 执行了提交,但是事务 A 还没有提交或回滚,这种事务并发问题称为不可重复读

不可重复读: 一个事务读取到其他事务已提交的数据导致前后两次读取数据不一样的情况

三、幻读

MySQL 事务特性和事务隔离级别_事务隔离级别_03

测试可重复读: 将事务隔离级别修改为可重复读



  1. ​# REPEATABLE-READ 可重复读(默认的事务隔离级别)​
  2. ​set session transaction isolation level repeatable read;​

幻读: 一个事务前后两次读取的数据不一致,是因为其他事务插入数据导致的事务并发情况

3. MySQL 事务的隔离级别


MySQL 事务有四种隔离级别,如下所示,表格中的 “是” 代表存在这个问题,“否” 代表没有这个问题

隔离级别

脏读

不可重复读

幻读

Read uncommitted(读未提交)




Read committed(读已提交)




Repeatable read(可重复读,默认的隔离级别)




Serializable(可串行化)




查看事务隔离级别



  1. ​# 查看全局事务隔离级别​
  2. ​select @@global.tx_isolation;​

  3. ​# 查看会话事务隔离级别(也就是当前窗口)​
  4. ​select @@tx_isolation;​
  5. ​select @@transaction_isolation;​

设置事务隔离级别



  1. ​# 读未提交​
  2. ​set session transaction isolation level read uncommitted;​
  3. ​# 读已提交​
  4. ​set session transaction isolation level read committed;​
  5. ​# 可重复读(默认隔离级别)​
  6. ​set session transaction isolation level repeatable read;​
  7. ​# 可串行化​
  8. ​set session transaction isolation level serializable;​

总结:

MySQL 的默认隔离级别是可重复读,不是读已提交

隔离性从低到高分别是:读未提交、读已提交、可重复读、可串行化

并发性跟隔离性恰好相反,从低到高是:可串行化、可重复读、读已提交、读未提交

这也非常好理解,隔离性越高,说明锁的粒度越细,并发性自然就会降低

标签:事务,隔离,isolation,提交,MySQL,级别
From: https://blog.51cto.com/10zhancom/6008371

相关文章

  • 用Jersey构建RESTful服务5--Jersey+MySQL5.6+Hibernate4.3
    一、总体说明本例运行演示了用Jersey构建RESTful服务中,如何同过Hibernate将数据持久化进MySQL的过程二、环境1.上文的项目RestDemo2.MySQL5.6下载​​http://dev.mysql.com/......
  • 【MySQL】MySQL8安装
    1.MySQL8安装安装环境操作系统:CentOS7MySQL版本:8.0.28安装方式:二进制Generic软件路径:/app/database数据路径:/data/3306日志路径:/binlog/3306MySQLCommunitySe......
  • MySql查看数据库及表容量大小并排序
    MySql查看数据库及表容量大小并排序带刀医生关注IP属地:江苏2022.04.1120:05:34字数85阅读1,219MySql查看数据库及表容量⼤⼩并排序查看所有数据库容量⼤⼩......
  • 自己动手写一个Mysql到PostgreSQL数据库迁移工具
    1.前言这段时间在进行Mysql到PostgreSQL数据库迁移工作.主要包含三部分工作,其一是构建数据库对象,包括表,视图,存储过程的构建,这部分由于我在项目早期就引入了li......
  • docker之Mysql安装教程
    部署mysql:5.7安装mkdir-p/app/docker/mysql/logmkdir-p/app/docker/mysql/datamkdir-p/app/docker/mysql/confdockerpullmysql:5.7dockerrun-d-p3......
  • mysql01-基础操作-增删查改
    连接mysqlmysql-uroot-p数据库操作创建数据库createDATABASE<数据库名>;删除数据库dropdatabase数据库名;选择数据库use数据库名;表操作创建表CREATET......
  • mysql索引优化-01
    1.1索引是什么?  mysql官方对于索引的定义:可以帮助mysql高效的获取数据的数据结构。  mysql在存储数据之外,数据库系统中还维护着满足特定查找算法的数据结构,这些数据......
  • mysql进阶
    事务 要么都成功,要么都失败ACID原子,一致,持久,隔离原子性,一致性,隔离性,持久性原子性:要么都成功,要么都失败回滚一致性:事务前后的数据完整性要保证一致持久性:事务一......
  • mysql like性能优化
    网上很多优化like的方法,无非下面几种,抄来抄去的。我用213万条数据,每条数据50个字段左右(用的真实的生产环境的mysql数据库,和真实的生产环境的数据),做了性能测试;时间记录的次数......
  • mysql 处理空格数据
    mysql中有处理空格的函数,做个简单介绍:1.TRIM()函数这个函数的用法很简单,但是无法去除中间的空格--去除左右空格SELECTTRIM('fdfd');SELECTTRIM(BOTH''FROM'......