锁问题
通过锁定机制可以实现事务的隔离性要求,使得事务可以并发地工作。锁提高了并发,但是却会带来潜在地问题。不过好在因为事务隔离性地要求。锁只会带来三种问题,如果可以防止这三种情况地发生,那将不会产生并发异常。
1、脏读
脏读(Dirty Read),首先理解一下脏数据地概念。
脏页:是指在缓冲池中已经被修改地页,但是还没有刷新到磁盘中,即数据库实例内存中地页和磁盘中的页数据是不一致的。
脏数据:是指事务对缓冲池中行记录的修改,并且还没有被提交。
脏读指的就是在不同事务下,当前事务可以读到另外事务未提交的数据,简单来说就是可以读到脏数据。
脏读现象的发生条件是需要事务的隔离级别为 READ UNCOMMITTED.
InnoDB存储引擎默认的事务隔离级别为 REPEATABLE READ;
SQL Server 数据库为 READ COMMITTED;
Oracle数据库同样也是 READ COMMITTED;
2、不可重复读
不可重复读是指在一个事务内多次读取同一数据集合,发生了事务读取不一致情况。
不可重复读和脏读的区别是:脏读是读到未提交的数据,而不可重复读读到的确是已经提交的数据,但是其违反了数据库事务一致性(事务开始和完成时数据保持一致)的要求。
事务隔离级别 READ COMMITTED 解决不了不可重复读是因为在MVCC 中查询读取的数据的快照版本数据是被锁定行的最新一份快照数据。
事务隔离级别 REPEATABLE READ 可以防止不可重复读是因为在MVCC中查询的快照数据总是读取事务开始时的行数据版本。
3、丢失更新(幻读)
丢失更新时另一个锁导致的问题,简单来说其实就是一个事务的更新操作会被另一个事务的更新操作所覆盖,从而导致数据的不一致。
要避免丢失更新发生,需要让事务在这种情况下测操作变成串行化,而不是并行的操作。两个事务同时查询,更新数据,事务A查询数据加上一个排他X锁,事务B就需要等待事务A操作完成后才可以进行操作。
不可重复读侧重于修改
幻读侧重于新增和删除
解决不可重复读的问题只需要锁住满足条件的行,解决幻读需要锁表