事务的隔离级别 #
事务并发执行遇到的问题 #
当数据库上多个事务并发执行的时候,就可能出现脏写(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
。