自己对sql四个事务隔离性级别的理解
前言
所谓隔离性级别,就是指给一个事务(一旦开始)多大的权限,对自己的读写有怎样的限制。
另外,隔离性级别是针对一个数据库系统中所有事务而言的。对于多个并发的事务来说,彼此之间互相都是『其它的事务』。A不允许B做的事情,在B看来也是自己对A的限制。
很多文章把『隔离性级别』和『在某种隔离性级别下可能的对数据一致性的风险』这两件事写在一起,不作区隔,自然而然让人头大。
可能的风险是指可能性,只要有可能就会写下来。有时候有人会想,怎么可能会有这样的操作呢?这操作会是什么具体的场景?这是无关紧要的。实际上,这种操作真的出现在实际生活和场景中的出现率极低,也正因此这些级别尽管存在风险但仍被采用以追求数据库的效率。
『幻读 虚读 phantom read』,『脏读 dirty read』和『不可重复读 non-repeatble read』均不是任何隔离级别的别称,而是对某种可能的风险的概括性名称。
按本文顺序由上往下所对应的级别的可能风险的危害越来越大,并发程度越来越高,限制越来越少。并且下一级的可能风险一定包含上一级的可能风险,只是不再写出。
强制串行化 serializable
运行中的事务的权限最大,可以并且必须阻止其它任何事务的发生。由于别的事务根本无法发生,所以并不需要限制自己的读写,可以认为没有限制。
可能的风险:没有风险。
可重复读 repeatable read
运行中的事务不能阻止其它事务并发地同时运转,但自己读取到的记录对其它事务完全屏蔽,但不禁止其它事务访问自己在使用的表和其它记录。
可能的风险:对于被事务操作的数据不会出问题,但数据所在的表以及其它数据可能会变的和事务刚开始读数据时的不一样,即幻读、虚读。
这一级别的可能的风险的危害不大,但相比于强制串行化,允许了并发,带来了性能上的提升,所以这一级别被广泛使用。
读已提交 read committed
运行中的事务不能阻止其它事务并发地同时运转,对其它事务禁止对自己读取到的数据的修改,但不禁止读取。
可能的风险:事务t1读取数据A后,事务t2可以读到数据A的值但不能修改,等到事务t1提交结束后,事务t2手上的数据A的值已经过时(被变更)了。又或者说事务t2在事务t1前后两次读数据A的结果不一样,即不可重复读。
这一级别的可能的风险危害已经严重了一些,但其带来了更高的并发性,也有采用。
读未提交 read uncommited
事务彼此之间完全没有限制。
可能的风险:仓库管理员统计仓库中钢铁的数量(事务t1),此时一个车队拉了一吨钢铁进仓库(事务t2),导致仓库管理员认为钢铁仓库数量足够,结束统计(结束事务t1)。但车队进了仓库之后没有停留就开走了(事务t2未提交并且事务t2失败了并且回滚了),导致仓库中钢铁数量根本不够。这种读取到了一个还未提交的事务读写的读写的行为,即为脏读。
其风险发生的可能性高,危害程度大,即便并发性再好也不允许,不被任何数据库系统采用。