事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列。事务ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

 
数据库事务隔离级别共4个,由低到高依次为Readuncommitted、Readcommitted、Repeatableread、Serializable。
Isolation level Dirty reads Non-repeatable reads Phantoms
Read Uncommitted may occur may occur may occur
Read Committed don't occur may occur may occur
Repeatable Read don't occur don't occur may occur
Serializable don't occur don't occur don't occur
 
1.Read Uncommitted读未提交
 
A事务 B事务
读余额为2000元  
  转出1000元
再次读余额为1000元  
  发现不对,回滚转出的1000元
再次读余额为2000元,很纳闷  
 
 
 
 
 
 
 
 
 
总结:B事务还没提交,A事务就能实时读到数据,出现脏读
 
.Read Committed读提交

Read committed 是一个很受欢迎的隔离级别. 像Oracle 11g, PostgreSQL, SQL Server 2012, MemSQL等都是默认此隔离级别的。

  2.1 它保证了下面两种情况:

  1. When reading from the database, you will only see data that has been committed (no dirty reads).

 

  如上图所示,User1只会读取到User2已经提交了的数据。

  for every object that is written, the database remembers both the old committed value and the new value set by the transaction that currently holds the write lock.

  While the transaction is ongoing, any other transactions that read the object are simply given the old value. Only when the new value is committed do transactions switch over to reading the new value.

  (当每个对象在写的时候,数据库会记住已经被提交的旧值和当前事务持有写锁设置的新值。当一个事务还在进行中,那么其他事务读取到的就是旧值。只有当新值被提交的时候才会被其他事务读取到。)

  2. When writing to the database, you will only overwrite data that has been committed (no dirty writes).

  Most commonly, databases prevent dirty writes by using row-level locks: when a transaction wants to modify a particular object (row or document), it must first acquire a lock on that object.

  It must then hold that lock until the transaction is com‐ mitted or aborted. Only one transaction can hold the lock for any given object; if another transaction wants to write to the same object,

  it must wait until the first transaction is committed or aborted before it can acquire the lock and continue. This locking is done automatically by databases in read committed mode (or stronger iso‐ lation levels).

  (通常数据库避免脏写是使用了行级锁,当一个事务想要去修改数据时,它会首先得到这个数据对象的锁,直到事务提交或者回滚。而且只有一个事务能够持有这个锁;

  如果其他事务想要去写相同的数据对象,它必须等到上一个事务提交或者回滚然后去得到这把锁。这种锁机制是数据库在read committed或者更高的隔离级别下自动做到的。)

  2.2 虽然RC隔离级别下能够防止脏读和脏写,但是会出现不可重复读或者读倾斜(nonrepeatable read or read skew ),如下图情况

正是因为事务可以读取到另一个事务已经提交的数据,所以Alice读取到的数据在有Transfer和没有Transfer两种情况下,会不一样。

为了解决这种问题,数据库提供了snapshot isolation (快照隔离),也就是multi-version concurrency control (MVCC) 。

笼统点说,就是事务12的所有快照读只会读取created by版本号小于等于自己的快照数据。

这儿有一篇形象点的关于MVCC的文章:https://blog.csdn.net/whoamiyang/article/details/51901888

 
.Repeatableread可重复读(在mysql中也就是snapshot isolation)
 
  在RR隔离级别下基于MVCC解决了不可重复读的问题,但是事务的修改其实是已经发生了的,如果当前事务对读到的数据做出写操作,那么可能就会发生问题。

  Alice和Bob都是基于快照读去做自己的逻辑操作,这就导致写倾斜(write skew )。

  其实在RR隔离级别下,Lost updates、Write skew、Phantom reads都是有可能发生的,

  在禁用innodb_locks_unsafe_for_binlog(5.6版本已弃用)的情况下,在搜索和扫描index的时候使用的next-keylocks可以避免幻读。

  我的理解是,在一个事务开启但没有结束之前,SELECT FOR UPDATE(当前读) 会给查询行数据加上next-key locks,对于同一张表而言,事务之间就是串行化的了。

  具体的加锁细节还需要区分查询条件,以及索引的设置等,关于mysql数据库事务锁分析的:https://www.cnblogs.com/zhaoyl/p/4121010.html

 
.Serializable序列化

A事务 B事务
代码A1  
代码A2  
  代码B1
  代码B2
 
 
 
 
 
 
  A事务先开始,就一条一条执行,直到事务结束,才开始B事务,一条一条执行,直到事务结束。解决了所有问题,但是代价最高,性能很低,一般很少使用。
  Implementation of two-phase
    •  If transaction A has read an object and transaction B wants to write to that object, B must wait until A commits or aborts before it can continue.(This ensures that B can’t change the object unexpectedly behind A’s back.)

    •  If transaction A has written an object and transaction B wants to read that object, B must wait until A commits or aborts before it can continue.

  两阶段加锁,写操作不仅会阻塞其他的写操作也会阻塞读操作,快照隔离(MVCC)读不会阻塞写操作,写操作也不会阻塞读操作,这也是两者关键的不同点。

  在mysql中两阶段加锁就用来实现串行化隔离级别。

  两阶段分别是事务执行时期的加锁阶段和事务提交或者回滚的解锁阶段。

5总结:

Dirty reads

  One client reads another client’s writes before they have been committed. The read committed isolation level and stronger levels prevent dirty reads.

  (事务1读取到另一个事务还没有提交的写操作数据,RC及其以上隔离级别能避免脏读)

Dirty writes

  One client overwrites data that another client has written, but not yet committed. Almost all transaction implementations prevent dirty writes.

  (事务1覆盖写了其他事务还没有提交的写操作,通常所有的事务实现都能避免脏写)

Read skew (nonrepeatable reads)

  A client sees different parts of the database at different points in time. This issue is most commonly prevented with snapshot isolation,

  which allows a transaction to read from a consistent snapshot at one point in time. It is usually implemented with multi-version concurrency control (MVCC).

  (事务在不同时间点看到不同的数据。通常是用快照隔离去避免它,快照隔离允许一个事务读取某个时间点的快照版本。它通常由MVCC实现。)

Lost updates

  Two clients concurrently perform a read-modify-write cycle. One overwrites the other’s write without incorporating its changes, so data is lost.

  Some implementations of snapshot isolation prevent this anomaly automatically, while others require a manual lock (SELECT FOR UPDATE).

  (两个事务同时的循环去读取-修改-写。其中一个覆盖写了其他事务没有合并的修改,所有导致数据丢失。有些实现基于快照读可以自动避免修改丢失,然而有些就需要人为的加锁(SELECT FOR UPDATE))

Write skew

  A transaction reads something, makes a decision based on the value it saw, and writes the decision to the database.

  However, by the time the write is made, the premise of the decision is no longer true. Only serializable isolation prevents this anomaly.

  (一个事务根据当前读取到的数据做了一些决策,然后把这些决策写入数据库。然而到写的时候,这个决策的前提不再正确了。仅仅只有serializable才能避免这种情况)

Phantom reads

  A transaction reads objects that match some search condition. Another client makes a write that affects the results of that search.

  Snapshot isolation prevents straightforward phantom reads, but phantoms in the context of write skew require special treatment, such as index-range locks.

  (一个事务读取到匹配某些搜索条件的对象。其他事务写操作影响了这个搜索条件的结果。快照隔离能避免简单的幻读,但是在写倾斜的上下文中幻读需要特殊处理,比如index-range locks。)

注:文章中部分结论及图片引自《Designing.Data-Intensive.Applications》。

Mysql数据库事务隔离级别的更多相关文章

  1. mysql数据库——事务隔离级别

    四种隔离级别: 一:READ UNCOMMITTED(未提交读) 事务可以读取其他事务未提交的数据,称为脏读 二:READ COMMITTED(提交读) 一个事务开始时,只能"看见" ...

  2. MySQL数据库事务隔离级别(Transaction Isolation Level)

    转自: http://www.cnblogs.com/zemliu/archive/2012/06/17/2552301.html  数据库隔离级别有四种,应用<高性能mysql>一书中的 ...

  3. mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理

    一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...

  4. [转]MySQL 数据库事务隔离级别

    然后说说修改事务隔离级别的方法: 1. 全局修改,修改 mysql.ini 配置文件,在最后加上 1 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATAB ...

  5. 重新学习MySQL数据库8:MySQL的事务隔离级别实战

    重新学习Mysql数据库8:MySQL的事务隔离级别实战 在Mysql中,事务主要有四种隔离级别,今天我们主要是通过示例来比较下,四种隔离级别实际在应用中,会出现什么样的对应现象. Read unco ...

  6. 数据库事务隔离级ORACLE数据库事务隔离级别介绍

    本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committ ...

  7. 数据库事务隔离级别+Spring 声明性事务隔离级别

    数据库事务隔离级别 数据库提供了四种事务隔离级别, 不同的隔离级别采用不同的锁类开来实现. 在四种隔离级别中, Serializable的级别最高, Read Uncommited级别最低. 大多数数 ...

  8. Mysql数据库的隔离级别

    Mysql数据库的隔离级别有四种 1.read umcommitted   读未提交(当前事务可以读取其他事务没提交的数据,会读取到脏数据) 2.read committed 读已提交(当前事务不能读 ...

  9. Atitit.数据库事务隔离级别 attilax 总结

    Atitit.数据库事务隔离级别 1. 事务隔离级别的作用 1 2. 在的隔离级别 2 3. 常见数据库的默认管理级别 3 1. 事务隔离级别的作用 较低的隔离级别可以增强许多用户同时访问数据的能力, ...

随机推荐

  1. 【剑指Offer学习】【面试题:二维数组中的查找】PHP实现

    最近一直看剑指Offer.里面很多算法题.于是就想着用PHP来显示一下. 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的 ...

  2. 初始css

    1.CSS规则由两部分构成,即选择器和声明器 声明必须放在{}中并且声明可以是一条或者多条 每条声明由一个属性和值构成,属性和值用冒号分开,每条语句用英文冒号分开 注意: css的最后一条声明,用以结 ...

  3. Java面试总结(二)

    前几天去了几家公司面试,果然,基本全部倒在二面上,无语啊...不过幸好,到最后拿到了环球易购的offer,打算就这么好好呆着了,学习学习,努力努力,下面讲讲这几天的面试吧. 先是恒大,一个组长面试,答 ...

  4. 分享两个提高效率的AndroidStudio小技巧

    这次分享两个 Android Studio 的小技巧,能够有效提高效率和减少犯错,尤其是在团队协作开发中. Getter 模板修改--自动处理 null 判断 格式化代码自动整理方法位置--广度 or ...

  5. 想不到的:js中加号操作符

    研究js加号操作符的时候,无意中试验了一个 console.log({} + "str");//NaN 发现结果居然是NaN,这让我百思不得其解. 我查阅资料,js高级编程里是这样 ...

  6. C语言第二周作业——分支结构

    一.PTA实验作业 题目1.7-1计算分段函数 本题目要求计算下列分段函数f(x)的值: 1实验代码 double x,result; scanf("%lf",&x); i ...

  7. APP案例分析--扇贝单词

    APP案例分析 一.调研 1.第一次上手   第一次使用时,一进APP,有一个每日一句,然后就是登录界面.有点不舒服,我都还不知道你这个APP好不好用,不让我体验一下就要注册.简单的测试了我的英语水平 ...

  8. BEM 中文翻译

    BEM 原文请看 getBEM Introduction(介绍) Block 独立实体,独立的意义 Examples:header, container, menu, checkbox, input ...

  9. RocketMQ(二):RPC通讯

    匠心零度 转载请注明原创出处,谢谢! RocketMQ网络部署图 NameServer:在系统中是做命名服务,更新和发现 broker服务. Broker-Master:broker 消息主机服务器. ...

  10. php面向对象相关内容

    1.什么是面向对象? 面向对象编程(Object Oriented Programming, OOP, 面向对象程序设计)是一种计算机编程架构,OOP的一条基本原则是计算机程序是由单个能够起到子程序作 ...