数据库隔离级别

数据库隔离级别是针对有两个或多个事务同时执行时,对数据和操作进行安全保护的一种锁机制。

一,事务

使用START TRANSACTION;开始一个事务,然后要么用COMMIT提交事务,将修改的数据持久保留,要么使用ROLLBACK撤销所有的修改。

START TRANSACTION;
select ...;
update ...
instert ...
delete ...
COMMIT;

或者:

START TRANSACTION;
select ...;
update ...
instert ...
delete ...
ROLLBACK;

事务具有ACID特性:

  • atomicity,原子性,即一个事务是不可分割的最小执行单元。要么全部执行成功,要么全部执行失败。
  • consistency。一致性。数据库总是从一个一致性的状态转换到另一个一致性的状态。
  • isolation,隔离性。通常一个事务在提交之前所做的修改,在其他事务是不可见的。后面的数据库隔离级别会详讲。
  • durability,持久性。事务一旦提交,其所做的修改就会永久保存到数据库中。

一个兼容ACID特定的数据库系统,需要做很多复杂但可能用户并没有察觉到的工作。

二,隔离级别

一般的数据库有如下4种隔离级别,不同的存储引擎的隔离级别也不相同。mysql的默认隔离级别是幻读(可重复读)。

  • 脏读
  • 不可重复读
  • 幻读
  • 串行化
1,未提交读(脏读)

A事务中未提交的内容,在B事务中都可见。如果A事务回滚,B事务读到的数据就是脏数据。

2,提交读(不可重复读)

A事务需要执行很长时间,在t1时刻读到某行记录 col1 = 100,在t2时刻B事务将这行记录 col1 改成 101,并顺利提交,在t3时刻A事务读到这行记录 col1 就是 101,跟t1时刻读取的不一致。这称为不可重复读。
解决办法:加行锁

3,可重复读(幻读)

A事务需要执行很长时间,t1时刻读取某个用户的记录有100条。t2时刻B事务又插入50条这个用户的记录并提交,t3时刻A事务读取这个用户的记录有150条,跟第一次读取的100条不一致。这称为幻读。
解决办法:加表锁

4,可传行化

强制事务串行执行。

三,MVCC多版本控制

前面提到,mysql默认的可重复读有幻读的问题。可以通过加表锁来解决幻读的问题,但是并发性支持就不好。MVCC就是为了解决:在提供高并发度支持的前提下,解决幻读的问题。