数据库事务隔离级别和锁的实现方式

来源:互联网 发布:数据专业问答题 编辑:程序博客网 时间:2024/05/22 09:07

    当数据库中多个事务(Transaction)处理同一数据时,就会出现并发的问题,也就是需要解决数据库隔离性的问题(isolation)。

    数据库的事务操作主要会碰到以下几类问题:

    1.脏读:脏读指的是当前事务读到了其他事务未提交(uncommitted)的数据;

    2.不可重复读:本处的不可重复指的是在同一事务中,本事务未修改数据的情况下,两次读取的数据不一致;

    3.虚读:虚读类似于不可重复读,只不过读取的不是数据库中某一行数据,而是一类数据,因此其余事务即使只是插入新的数据,也会对本事务的读产生影响;

    4.第一类更新丢失:第一类更新丢失值得是,某一事物回滚(rollback)导致其他事务提交的数据被覆盖;

    5.第二类更新丢失:本质和不可更新读一样,出现于不知道其他事务更新操作的存在。


    知道了,以上的几个问题,我们来看看数据库事务的隔离级别是如何解决这些问题的:

    1.Read uncommitted 读未提交数据:能解决第一类丢失更新的问题,但不能解决脏读的问题

实现原理是,读数据时候不加锁,写数据时候加行级别的共享锁,提交时释放锁。行级别的共享锁,不会对读产生影响,但是可以防止两个同时的写操作。


    2.Read committed 读提交数据:能解决脏读的问题,但是不能解决不可重复读的问题:

实现原理是,事务读取数据(读到数据的时候)加行级共享锁,读完释放;事务写数据时候(写操作发生的瞬间)加行级独占锁,事务结束释放。由于事务写操作加上独占锁,因此事务写操作时,读操作也不能进行,因此,不能读到事务的未提交数据,避免了脏读的问题。但是由于,读操作的锁加在读上面,而不是加在事务之上,所以,在同一事务的两次读操作之间可以插入其他事务的写操作,所以可能发生不可重复读的问题。


    3.Repeated Read 可重复读:顾名思义,可以解决不可重复读的问题,但是不能解决虚读问题:

实现原理,和读提交数据不同的是,事务读取数据在读操作开始的瞬间就加上行级共享锁,而且在事务结束的时候才释放。分析方法和读提交数据类似,本处不再赘述。但是,由于加锁只是加在行上,所以,仍然可能发生虚读的问题。


    4. Serializable 串行化:可以解决以上所有的并发问题:

实现原理是,在读操作时,加表级共享锁,事务结束时释放;写操作时候,加表级独占锁,事务结束时释放。

0 0