转载自:https://my.oschina.net/huangyong/blog/160012
什么是事务
事务通俗理解就是做一件事情要有始有终,不能半途而废。 要么做,要么不做。也就是说,事务是一个不可分割的整体。
事务的特性(ACDI):
- 原子性(Atomicity):事务具有原子性,就像课本中学的,原子是构成物质的最小单位,不可分割。
-
隔离性(Isolation):保证数据库操作之间是“隔离”的(线程之间有时也要做到隔离),彼此之间没有任何干扰。
例:当我们编写了一条 update 语句,提交到数据库的一刹那间,有可能别人也提交了一条 delete 语句到数据库中,这个时候如果操作的是同一条数据,会出现很大的问题。 -
一致性(Consistency):执行完数据库操作后,数据不会被破坏,这个在数据领域是非常重要的特性。
例:如果从 A 账户转账到 B 账户,不可能A 账户扣了钱,而 B 账户没有加钱吧。 - 持久性(Durability):执行一条 insert 语句后,数据库必须要保证有一条数据永久地存放在磁盘中,这个也算事务的一条特性。
什么是隔离级别
当我们编写了一条 update 语句,提交到数据库的一刹那间,有可能别人也提交了一条 delete 语句到数据库中,这个时候如果操作的是同一条数据,会出现很大的问题。所以保证数据库操作之间是“隔离”的(线程之间有时也要做到隔离),彼此之间没有任何干扰。这就是隔离性。
为了做到操作之间完全没有任何干扰,于是,就有了事务隔离级别(Transaction Isolation Level)规范。
注意:我们讨论隔离级别的场景,主要是在多个事务并发的情况下,因此,接下来的讲解都围绕事务并发。
隔离级别共四个级别:从上往下,级别越来越高,并发性越来越差,安全性越来越高,反之则反。 **
Read uncommitted(读未提交 )
Read committed(读提交)
Repeatable read(重复读)(Mysql默认隔离级别)
Serializable(序列化:最高级别的事务隔离,花费高,性能低,一般很少用)
**
这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。
事务的四个特性之间的相互关系
原子性是基础,隔离性是手段,持久性是目的,真正的boss是一致性。
这四个特性当中,其实最难理解的不是一致性,而是隔离性。因为它是保证一致性的重要手段,是工具,使用它不能有半点差池,否则后果自负!怪不得数据库行业专家们都要来研究所谓的事务隔离级别了。其实,定义这四个级别就是为了解决数据在高并发下所产生的问题,那又有哪些问题呢?
** Dirty Read(脏读)
Unrepeatable Read(不可重复读)
Phantom Read(幻读)
**
第一条,“脏读”其实就是我们常说的垃圾数据,例:
余额应该为 1500 元才对!请看 T5 时间点,事务 A 此时查询余额为 0 元,这个数据就是脏数据,它是事务 B 造成的,明显事务没有进行隔离,渗过来了,乱套了。
所以脏读这件事情是非常要不得的,一定要解决掉!让事务之间隔离起来才是硬道理。
脏读:事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。
那第 2 条,不可重复读又怎么解释呢?还是用类似的例子来说明:
事务 A 其实除了查询了两次以外,其他什么事情都没有做,结果钱就从 1000 变成 0 了,这就是重复读了。可想而知,这是别人干的,不是我干的。其实这样也是合理的,毕竟事务 B 提交了事务,数据库将结果进行了持久化,所以事务 A 再次读取自然就发生了变化。
这种现象基本上是可以理解的,但在有些变态的场景下却是不允许的。毕竟这种现象也是事务之间没有隔离所造成的,但我们对于这种问题,似乎可以忽略。
** 不可重复读:事务 A 读取了事务 B 已提交的更改数据。 **
最后一条,幻读。我去!Phantom 这个单词不就是“幽灵、鬼魂”吗?刚看到这个单词时,真的把我的小弟弟都给惊呆了。怪不得这里要翻译成“幻读”了,总不能翻译成“幽灵读”、“鬼魂读”吧。其实意义就是鬼在读,不是人在读,或者说搞不清楚为什么,它就变了,很晕,真的很晕。还是用一个示例来说话吧:
银行工作人员,每次统计总存款,都看到不一样的结果。不过这也确实也挺正常的,总存款增多了,肯定是这个时候有人在存钱。但是如果银行系统真的这样设计,那算是玩完了。这同样也是事务没有隔离所造成的,但对于大多数应用系统而言,这似乎也是正常的,可以理解,也是允许的。银行里那些恶心的那些系统,要求非常严密,统计的时候,甚至会将所有的其他操作给隔离开,这种隔离级别就算非常高了(估计要到 SERIALIZABLE 级别了)。
事务 A 读取了事务 B 已提交的新增数据。
以上三种情况,第一种情况是肯定不能发生,后两种情况视情况而定。
这就是为什么必须要有事务隔离级别这个东西了,它就像一面墙一样,隔离不同的事务。