一、事务(Transaction)的基本要素(ACID)

1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

二、并发访问会导致的问题

脏读:指一个线程中的事务读取到了另外一个线程中未提交的数据;

ex:事务A select data = 100,事务B此时更新 data = 200,还未提交,事务A再次 select data = 200,如果事务B回滚,那么A得到的200就是脏数据。

不可重复读(虚读):指一个线程中的事务读取到了另外一个线程中提交的update的数据;该现象由事务更新造成;

ex:事务A select data 发现 data = 100,此时事务B 更新data = 200 并提交,事务A又 select data 发现此时 data 从100变成了200,数据出现了不一致现象。

幻读:指一个线程中的事务读取到了另外一个线程中提交的insert or delete的数据;该现象由事务删除或者新增造成;

ex: 事务A select data 发现数据 data 不存在,于是准备insert data,事务B在A事务之前insert data 导致事务A insert data 失败,事务A好像幻觉一样,怎么 data 出现了?

三、隔离(Isolation)级别简介

1、读未提交 READ-UNCOMMITTED:一个事务可以读另一个事务未提交的数据;该隔离级别会导致脏读、不可重复读取现象,幻读;

2、读已提交 READ-COMMITTED:一个事务只能读另一个事务提交的数据;该隔离级别会导致不能重复读取和幻读现象;解决了脏读现象;

3、可重复读 REPEATABLE-READ:一个事务可重复读另一个事务提交的数据;该隔离级别会导致幻读现象;解决了脏读现象和不能重复读取的现象;

4、序列化 SERIALIZABLE:该隔离级别解决所有并发访问会导致的问题,解决了脏读现、不可重复读现和幻读现象;

PS:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

补充:

1、事务隔离级别为读提交时,写数据只会锁住相应的行

2、事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。

3、事务隔离级别为串行化时,读写数据都会锁住整张表

4、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。