Oracle 和 DB2,比较与兼容性/进程模型/锁定/Oracle
在最高级别,Oracle 以这种方式运行 - 阅读者不会阻塞阅读者。如果您正在读取数据,则无需等待其他正在读取相同数据的人。写入者不会阻塞阅读者 - 如果您正在读取数据,则无需等待正在写入同一块的用户。写入者只会阻塞其他正在写入同一块的写入者。
Oracle 中称为 SERIALIZABLE 的隔离级别实际上是快照隔离。快照隔离通过获取数据的“快照”来工作 - 称为读一致数据映像。所有读取都看到此快照,并且事务只有在它所做的任何更新与自该快照以来所做的任何并发更新没有冲突时才会成功提交。
由于 Oracle 不保证某些事务的串行排序会导致相同的结果,因此这与 ANSI/ISO 标准直接矛盾。使用它的原因是它的性能比可串行化更好,并且避免了并发异常。快照隔离与多版本并发控制 (MVCC) 密切相关。
Oracle 的锁定机制与其事务控制紧密耦合。其想法是,如果您正确设计了事务,则不必担心锁定,因为 DBMS 会自动为您获取锁定。话虽如此,Oracle 确实允许用户在需要时手动获取锁定。Oracle 锁定适用于用户对象(表和行)和用户不可见的系统对象(内存中的共享数据结构和数据字典行)。Oracle 尝试在尽可能低的级别获取锁定以确保高水平的数据并发。
Oracle 有两个级别的锁定,独占和共享。独占锁定用于修改数据。第一个获得独占锁的事务是唯一可以更改该对象的事务,直到锁被释放。共享锁定允许锁定对象被共享(取决于所涉及的操作)。多个用户读取数据可以通过持有共享锁来共享数据,这将阻止写入者访问相同数据,因为它需要独占锁。
在一个事务中获取的所有锁都将在事务持续期间保持,以防止诸如脏读、丢失更新和破坏性 DDL 操作(即,一个事务在另一个事务尝试插入时删除表)之类的事情。由一个事务所做的更改只对在第一个事务提交后开始的其他事务可见(读一致数据映像)。
Oracle 在提交或事务回滚(撤消)时释放锁。在回滚到先前保存点时也会释放锁。在回滚到保存点时,只有不在等待先前锁定资源的事务才能在新的可用资源上获得锁。在事务开始时等待的事务会回滚到一个保存点,它将继续等待,直到原始事务完全提交或回滚。
对在事务中插入、更新或删除的所有行获取独占行锁。行锁在最高限制级别获取,因此在获取行锁后不需要转换行锁。但是,Oracle 可以转换表锁。带有 FOR UPDATE 子句的 SELECT 语句将获取独占行锁和表的行共享表锁。如果事务后来更新了一个或多个锁定的行,则行共享表锁将自动转换为行独占表锁。这是一个锁定转换的例子。
Oracle 从不升级锁定。锁定升级发生在数据库需要将在一个粒度级别(例如行)持有的锁定提升到更高级别(例如表)时。一个例子是,如果用户在一个表中有几个行锁,而数据库将用户的行锁提升到表锁。这减少了锁定的数量,但增加了被锁定内容的限制性,因此死锁的可能性也增加了。