MySQL ACID及四种隔离级别的解释
以下内容出自《高性能MySQL》第三版,了解事务的ACID及四种隔离级有助于我们更好的理解事务运作。
下面举一个银行应用是解释事务必要性的一个经典例子。假如一个银行的数据库有两张表:支票表(checking)和储蓄表(savings)。现在要从用户Jane的支票账户转移200美元到她的储蓄账户,那么至少需要三个步骤:
1、检查支票账户的余额高于或者等于200美元。
2、从支票账户余额中减去200美元。
3、在储蓄帐户余额中增加200美元。
上述三个步骤的操作必须打包在一个事务中,任何一个步骤失败,则必须回滚所有的步骤。
可以用START TRANSACTION语句开始一个事务,然后要么使用COMMIT提交将修改的数据持久保存,要么使用ROLLBACK撤销所有的修改。事务SQL的样本如下:
1. start transaction;
2. select balance from checking where customer_id = 10233276;
3. update checking set balance = balance - 200.00 where customer_id = 10233276;
4. update savings set balance = balance + 200.00 where customer_id = 10233276;
5. commit;
ACID表示原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。一个很好的事务处理系统,必须具备这些标准特性:
原子性(atomicity)
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性
一致性(consistency)
数据库总是从一个一致性的状态转换到另一个一致性的状态。(在前面的例子中,一致性确保了,即使在执行第三、四条语句之间时系统崩溃,支票账户中也不会损失200美元,因为事务最终没有提交,所以事务中所做的修改也不会保存到数据库中。)
隔离性(isolation)
通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。(在前面的例子中,当执行完第三条语句、第四条语句还未开始时,此时有另外的一个账户汇总程序开始运行,则其看到支票帐户的余额并没有被减去200美元。)
持久性(durability)
一旦事务提交,则其所做的修改不会永久保存到数据库。(此时即使系统崩溃,修改的数据也不会丢失。持久性是个有占模糊的概念,因为实际上持久性也分很多不同的级别。有些持久性策略能够提供非常强的安全保障,而有些则未必,而且不可能有能做到100%的持久性保证的策略。)
隔离级别:
READ UNCOMMITTED(未提交读)
在READ UNCOMMITTED级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读(Dirty Read)。这个级别会导致很多问题,从性能上来说,READ UNCOMMITTED不会比其他的级别好太多,但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用。
READ COMMITTED(提交读)
大多数数据库系统的默认隔离级别都是READ COMMTTED(但MySQL不是)。READ COMMITTED满足前面提到的隔离性的简单定义:一个事务开始时,只能"看见"已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候叫做不可重复读(nonrepeatble read),因为两次执行同样的查询,可能会得到不一样的结果
REPEATABLE READ(可重复读)
REPEATABLE READ解决了脏读的问题。该隔离级别保证了在同一个事务中多次读取同样记录结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读(Phantom Read)的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)解决了幻读的问题。
SERIALIZABLE(可串行化)
SERIALIZABLE是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读的问题。简单来说,SERIALIZABLE会在读取每一行数据都加锁,所以可能导致大量的超时和锁争用问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。
打钩说明该隔离级别还存在这种情况,打X代表该隔离级别已经解决了这种情况:

|
作者:陆炫志 出处:xuanzhi的博客 http://www.cnblogs.com/xuanzhi201111 您的支持是对博主最大的鼓励,感谢您的认真阅读。本文版权归作者所有,欢迎转载,但请保留该声明。 |
MySQL ACID及四种隔离级别的解释的更多相关文章
- mysql ACID与四种隔离级别归纳总结
关于数据库的ACID特性已经有很多的介绍,这里再重新归纳总结一下: A(atomicity)原子性: 即事务要么全部做完,要么全部不做,不会出现只做一部分的情形,如A给B转帐,不会出现A的钱少了, ...
- MySQL中四种隔离级别的演示
事务的隔离是并发操作中需要理解清楚的问题.MySQL中共有4种不同的隔离级别,这4种隔离级别分别是: 隔离级别类型 影响结果 READ UNCOMMITTED(未提交读) 事务将会读取到未提交的数据, ...
- 数据库操作事物的四大特性以及MySQL数据库的四种隔离级别
1 .事物操作数据库的四大特性(ACID) 1.原子性 (Atomicity) 原子性:就是事物的所包含的所有操作,要么全部成功,要么全部失败回滚. 2.一致性 (Consistency) 一致性:简 ...
- MySQL表的四种分区类型
MySQL表的四种分区类型 一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过了600万条,那么就可以根据入库日期将表 ...
- linux下查看mysql版本的四种方法
Linux查看MySQL版本的四种方法 1 在终端下执行 mysql -V 2 在help中查找 mysql --help |grep Distrib 3 在mysql 里查看 select vers ...
- mysql启动的四种方式
mysql的四种启动方式: .mysqld 启动mysql服务器:./mysqld --defaults-file=/etc/my.cnf --user=root 客户端连接: mysql --def ...
- ThinkPHP中连接mysql数据库的四种实用和通用的连接方法
ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库适配器来处理.目前的数 ...
- MySql MediumBlob——MySql的Bolb四种类型
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据.BLOB类型实际是个类型系列(TinyBlob.Blob.MediumBlob.LongBlob),除 ...
- mysql锁及四种事务隔离级别笔记
前言 数据库是一个共享资源,为了充分利用数据库资源,发挥数据 库共享资源的特点,应该允许多个用户并行地存取数据库.但这样就会产生多个用户程序并 发存取同一数据的情况,为了避免破坏一致性,所以必须提供并 ...
随机推荐
- Java时间的转换
String DATE_FORMAT = "yyyy-MM-dd"; LocalDate localDate = LocalDate.now(); long startTime = ...
- Java线程池停止空闲线程是否有规则呢?
Java线程池中线程的数量超过核心线程的数量,且所有线程空闲,空闲时间超过keepAliveTime,会停止超过核心线程数量的线程,那么会保留哪些线程呢?是不是有规则呢? 测试代码: ThreadPo ...
- IDEA中新建Module时Module name、Content root、Module file location的含义
如下图测试: 最开始默认情况下,Content root.Module file location两行,最末尾的数据跟Module name是相同的. 现在对三行数据,强制进行不同的命名,Finish ...
- 【字符串算法2】浅谈Manacher算法
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 字符串算法2:Manacher算法 问题:给出字符串S(限制见后)求出最 ...
- 一个具有缓存数据功能的HttpWebRequest工具类
背景:一个公共站点中的数据,供其它子站点共享,为了提高性能,简单实现了Http 1.1的缓存功能 特点:可以缓存Html数据到内存中;缓存具有过期时间;缓存过期后,通过再确认的方式来决定是否更新缓存; ...
- MySQL命令行查询乱码解决办法
MySQL会出现中文乱码的原因不外乎下列几点: 1.server本身设定问题,例如还停留在latin1 2.table的语系设定问题(包含character与collation) 3.客户端程式(例如 ...
- JavaScript中的两种全局对象
这里总结的东西特别适合先学习c/c++, Java这类标准语言再学JS的童鞋们看,因为JS在程序执行之前就会初始化一个全局对象,这个全局对象到底是什么是跟JS程序运行环境有关的. 根据JavaScri ...
- 初识python面向对象编程
初识python面向对象编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.面向过程的程序设计思想 #!/usr/bin/env python #_*_coding:utf-8 ...
- Spark记录-Scala多线程
Scala多线程 多线程是同时执行多个线程的过程. 它允许您独立执行多个操作.可以通过使用多线程来实现多任务.线程是轻量级的子进程,占用较少的内存.多线程用于在Scala中开发并发应用程序. Scal ...
- 这两天自己模仿写的一个Asp.Net的显示分页方法 附加实体转换和存储过程
之前自己一直用Aspnetpager控件来显示项目中的分页,但是每次都要拖一个aspnetpager的控件进去,感觉很不舒服,因为现在自己写的webform都不用服务器控件了,所以自己仿照aspnet ...