事务的隔离级别

事务的隔离级别 #

事务并发执行遇到的问题 #

当数据库上多个事务并发执行的时候,就可能出现脏写(Dirty Write)、脏读(Dirty Read)、不可重复读(Non-Repeatable Read)、 幻读(Phantom Read)的问题。

问题按照严重性来排序:

脏写 > 脏读 > 不可重复读 > 幻读

脏写 #

“脏写"是指,一个事务修改了另一个未提交事务修改过的数据

脏读 #

“脏读"是指,一个事务读到了另一个未提交事务修改过的数据

不可重复读 #

“不可重复读"是指,一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值

如上图在 Session B 中提交了几个隐式事务(注意是隐式事务,意味着语句结束事务就提交了),这些事务都修改了 number 列为 1 的记录的列 name 的值,每 次事务提交之后,Session A 中的事务都可以查看到最新的值,这就是不可重复读。

幻读 #

“幻读"是指。一个事务先根据某些条件查询出了一些记录,然后另一个事务又向表中插入了一些符合这些条件的记录,第一个事务再次使用相同条件查询时,把另一个 事务插入的记录也读出来了

如上图,Session A 中的事务先根据条件 number > 0 这个条件查询表 hero,得到了 name 列值为’刘备’的记录;之后 Session B 中提交了一个隐式 事务,该事务向表 hero 中插入了一条新记录;之后 Session A 中的事务再根据相同的条件 number > 0 查询表 hero,得到的结果集中包含了 Session B 中的事务新插入的那条记录,这就是幻读。

那对于先前已经读到的记录,之后记录被别的事物删除了,导致又读取不到了,这种情况,算不算幻读?这不属于幻读,幻读只是重点强调了读取到了之前读取没 有获取到的记录。

四种隔离级别 #

为了解决事务并发执行遇到的问题,就有了隔离级别的概念。SQL 标准中设立了 4 个隔离级别:

  • READ UNCOMMITTED读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。
  • READ COMMITTED读已提交是指,一个事务提交之后,它做的变更才会被其他事务看到。
  • REPEATABLE READ可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
  • SERIALIZABLE可串行化是指,对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执 行完成,才能继续执行。

MySQL 的默认隔离级别为 REPEATABLE READ

事务隔离的实现 #