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

MySQL 的 事务和隔离级别

时间:2023-01-17 13:13:30浏览次数:43  
标签:事务 隔离 read 数据库 提交 MySQL 级别

事务是一组原子性的SQL查询,事务内的SQL语句,要么全部执行成功,要么全部执行失败。本节重点介绍事务的ACID和隔离级别。

1. ACID
提到事务,大家肯定都不陌生,和数据库打交道,我们都会用到事务。银行转账是解释事务的一个经典例子。银行数据库通常会有两张表:支票表和储蓄表。现在要从用户 A 的支票账户转账 100 元人民币到储蓄账户,一般是下面三个步骤:

检查支票账户的余额高于 100 元;
从支票账户余额减去 100 元;
在储蓄账户余额增加 100 元;
相应的 SQL 语句如下:

start transaction
select balance from checking where customer_name = 'A'
update checking set balance = balance - 100.00 where customer_name = 'A'
update savings set balance = balance + 100.00 where customer_name = 'A'
commit;
这三个步骤需要封装成一个事务,任何一个步骤失败,都必须回滚所有的步骤。简单的说,事务就是保证一组数据库操作,要么全部执行成功,要么全部执行失败。

一个优秀的事务处理机制,需要具备 ACID 特性,即原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。

原子性(atomicity):一个事务被视为一个完整的最小工作单元,事务中的数据库操作,要么全部执行成功,要么全部执行失败回滚,不能只成功执行了其中的一部分数据库操作;

一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态。在银行转账的例子中,即使执行到第四条 SQL 语句时失败,用户的支票账户也不会损失 100 元人民币,因为执行失败时,事务进行了回滚,所做的修改并没有保存到数据库中;

隔离性(isolation):通常来说,一个事物所做的修改在提交以前,对其他事务是不可见的。在银行转账的例子中,当执行完第三条 SQL 语句时,此时另外一个程序在汇总支票账户,它所查询到的用户A的支票账户,并没有减去 100 元人民币;

持久性(durability):事务提交成功,所做的修改就会永久保存到数据库中,即使系统崩溃,修改的数据也不会丢失。

原子性(atomicity):一个事务被视为一个完整的最小工作单元,事务中的数据库操作,要么全部执行成功,要么全部执行失败回滚,不能只成功执行了其中的一部分数据库操作;

一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态。在银行转账的例子中,即使执行到第四条 SQL 语句时失败,用户的支票账户也不会损失 100 元人民币,因为执行失败时,事务进行了回滚,所做的修改并没有保存到数据库中;

隔离性(isolation):通常来说,一个事物所做的修改在提交以前,对其他事务是不可见的。在银行转账的例子中,当执行完第三条 SQL 语句时,此时另外一个程序在汇总支票账户,它所查询到的用户A的支票账户,并没有减去 100 元人民币;

持久性(durability):事务提交成功,所做的修改就会永久保存到数据库中,即使系统崩溃,修改的数据也不会丢失。

在 MySQL 中,事务是在存储引擎层实现的。MySQL 是支持多种存储引擎的数据库,但并不是所有的存储引擎都支持事务,比如 MyISAM 就不支持事务。

事务增加了数据库的安全性,同时也需要数据库做很多额外的工作。相比没有实现 ACID 的数据库,实现了 ACID 的数据库需要更强的 CPU、内存、以及磁盘空间。

2. 隔离级别
在 SQL 标准中,包含了四种隔离级别,即未提交读(read uncommitted)、提交读(read committed)、可重复读(repeatable read)、可串行化(serializable)。

未提交读(read uncommitted):一个事务还未提交,它所做的变更能被别的事务看到。事务可以读取未提交的数据,被称为脏读(dirty read),这种隔离级别在实际应用中一般很少使用;

提交读(read committed):一个事务提交之后,它所做的变更才能被别的事务看到。大多数数据库的默认隔离级别是提交读(read committed),比如 Oracle;

可重复读(repeatable read):一个事务在执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。在可重复读隔离级别下,未提交变更对其他事务也是不可见的。该级别保证了在同一个事务中,多次读取同样记录的结果是一致的。MySQL 的默认事务隔离级别是可重复读(repeatable read);

可串行化(serializable):serializable 是最高的隔离级别。对同一行数据,读写都会进行加锁。当出现锁冲突时,后面访问的事务必须等前一个事务完成,才能继续执行。实际应用场景很少用到这种隔离级别,只有在非常需要确保数据一致性,而且可以接受没有并发的情况,才会使用这种隔离级别。

未提交读(read uncommitted):一个事务还未提交,它所做的变更能被别的事务看到。事务可以读取未提交的数据,被称为脏读(dirty read),这种隔离级别在实际应用中一般很少使用;

提交读(read committed):一个事务提交之后,它所做的变更才能被别的事务看到。大多数数据库的默认隔离级别是提交读(read committed),比如 Oracle;

可重复读(repeatable read):一个事务在执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。在可重复读隔离级别下,未提交变更对其他事务也是不可见的。该级别保证了在同一个事务中,多次读取同样记录的结果是一致的。MySQL 的默认事务隔离级别是可重复读(repeatable read);

可串行化(serializable):serializable 是最高的隔离级别。对同一行数据,读写都会进行加锁。当出现锁冲突时,后面访问的事务必须等前一个事务完成,才能继续执行。实际应用场景很少用到这种隔离级别,只有在非常需要确保数据一致性,而且可以接受没有并发的情况,才会使用这种隔离级别。

下表为 ANSI SQL 隔离级别:

隔离级别 脏读可能性 不可重复度可能性 幻读可能性 加锁读
未提交读(read uncommitted) yes yes yes no
提交读(read committed) no yes yes no
可重复读(repeatable read) no no yes no
可串行化(serializable) no no no yes
3. 小结
本小节主要介绍了事务的 ACID 和隔离级别。

ACID特性:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)

隔离级别:未提交读(read uncommitted)、提交读(read committed)、可重复读(repeatable read)、可串行化(serializable)

标签:事务,隔离,read,数据库,提交,MySQL,级别
From: https://www.cnblogs.com/10zhan/p/17057570.html

相关文章

  • mySql,Pgsql,kingbase连表更新
    原文链接:https://www.jianshu.com/p/0df5797f7b73Tablea:id|主键code|编码Tableb:id|主键aId|关联a表idcode|编码......
  • MySQL查询精度丢失、varchar与bigint之间隐式类型转换的问题
    数据库查询过滤失效。今天在测试库上做一个关联查询时出现了捞出多余的值的情况,现在换个表名重现一下再解释。做项目时遇到一个奇怪的问题,关于mysql查询精度会有所丢失的......
  • mysql主从复制延迟问题
    背景线上mysql主从复制一直处于延迟状态,查看主从状态显示如下:...Slave_IO_Running:YesSlave_SQL_Running:YesSeconds_Behind_Mast......
  • Mysql:分页查询优化
    分页查询优化最简单的select分页是这样的:select*fromuserlimit2000,10mysql实际上会默认orderbyidasc,然后再进行limit。这个有个问题是先对user表的所有数据......
  • MySQL安装-Linux版
    MySQL8.0.26-Linux版安装1.准备一台Linux服务器云服务器或者虚拟机都可以;Linux的版本为CentOS7;2.下载Linux版MySQL安装包https://downloads.mysql.com/archives/......
  • MySQL卸载-Linux版
    MySQL卸载-Linux版停止MySQL服务systemctlstopmysqld查询MySQL的安装文件rpm-qa|grep-imysql卸载上述查询出来的所有的MySQL安装包rpm-emysql-community......
  • linux中用命令导出、导入mysql数据库表
    一、导出数据1.使用场景:在没有数据库可视化工具的情况下备份导出数据库。命令如下:mysqldump-u用户名-p数据库名>数据库名.sqlmysqldump-uroot-pcity>city.sq......
  • MySQL的存储引擎
    MySQL体系结构连接层最上层是一些客户端和链接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证......
  • mysql定时备份并删除30天前的备份
    backupmysqldatariqi=$(date+%Y-%m-%d)mysqldump-h50.100.13.2-uroot-ptenx#cloud999-P3306-A--lock-tables=0|gzip>/opt/mysql-data-backup/all-data-$ri......
  • MySQL必知必会第十一章-使用数据处理函数
    使用数据处理函数函数与其他大多数计算机语言一样,SQL支持利用函数来处理数据。函数一般是在数据上执行的,它给数据的转换和处理提供了方便。注意:函数没有SQL的可移植性......