11

当我尝试在 db 表中插入/更新某些内容时,Oracle 会锁定整个表还是仅锁定正在插入/更新的行?

这是可以通过外部配置来控制的吗?

4

4 回答 4

18

我们可以使用 LOCK TABLE 命令显式地发出锁。 了解更多

否则,插入不会锁定任何其他行。由于 Oracle 的读取隔离模型,该行只存在于我们的会话中,直到我们提交它,所以没有其他人可以对它做任何事情。 了解更多

更新语句仅锁定受影响的行。除非我们使用 SELECT ... FOR UPDATE 实现了悲观锁定策略。 了解更多

最后,在 Oracle 中写入器不会阻塞读取器。因此,即使锁定的行也可以被其他会话读取,它们只是无法更改。 了解更多

此行为已融入 Oracle 内核,并且不可配置。


Justin 对表级 DDL 锁提出了一个很好的观点。该锁将导致在表上执行 DDL 的会话等到 DML 会话提交,除非 DDL 类似于 CREATE INDEX,在这种情况下它将立即失败并显示 ORA-00054。

于 2013-08-02T16:08:37.523 回答
7

这取决于您所说的“锁定”是什么意思。

对于人们可能关心的 99.9% 的事情,Oracle 会在修改行时获取行级锁。行级锁仍然允许读取器读取行(由于多版本读取一致性,写入器永远不会阻塞读取器,读取器永远不会进行脏读)。

如果您四处寻找v$lock,您会发现更新一行也会导致表上的锁被取消。但是那个锁只会阻止另一个会话对表执行 DDL。由于您实际上从一开始就不想在活动表上执行 DDL,这通常不会导致另一个会话等待锁定。

于 2013-08-02T16:08:25.740 回答
5

当执行常规 DML(UPDATE/DELETE/INSERT、MERGE 和 SELECT ... FOR UPDATE)时,oracle 获得 2 个锁。行级锁 (TX) - 这会在被触摸的特定行上获得锁,并且任何其他尝试修改同一行的事务都会被阻止,直到已经拥有它的事务完成。表级锁 (TM) - 当获得行锁 (TX) 时,还会获得一个额外的表锁,以防止在 DML 进行时发生任何 DDL 操作。

重要的是在什么模式下获得表锁。行共享锁 (RS),也称为子共享表锁 (SS),表示持有表锁的事务已锁定表中的行并打算更新它们。SS 锁是限制最少的表锁模式,为表提供最高程度的并发。

行独占锁 (RX),也称为子独占表锁 (SX),表示持有该锁的事务已更新表行或发出 SELECT ... FOR UPDATE。SX 锁允许其他事务同时查询、插入、更新、删除或锁定同一表中的行。因此,SX 锁允许多个事务同时获得同一张表的 SX 和 SS 锁。

一个事务持有的共享表锁 (S) 允许其他事务查询该表(不使用 SELECT ... FOR UPDATE),但仅当单个事务持有共享表锁时才允许更新。多个事务可能同时持有一个共享表锁,因此持有这个锁并不足以保证一个事务可以修改表。

共享行独占表锁 (SRX),也称为共享子独占表锁 (SSX),比共享表锁更具限制性。一次只有一个事务可以获取给定表上的 SSX 锁。事务持有的 SSX 锁允许其他事务查询表(SELECT ... FOR UPDATE 除外)但不能更新表。

排他表锁 (X) 是限制性最强的表锁模式,允许持有锁的事务对表进行排他性写访问。只有一个事务可以获得一张表的 X 锁。

于 2014-04-28T09:12:21.397 回答
0

您可能应该阅读有关锁定的 oracle 概念手册。对于标准 DML 操作(插入、更新、删除、合并),oracle 采用共享 DML(TM 类型)锁。这允许表上的其他 DML 同时发生(它是共享锁)。由更新或删除 DML 操作修改且尚未提交的行将具有排他行锁(TX 类型)。另一个会话/事务中的另一个 DML 操作可以对表进行操作,但如果它修改同一行,它将阻塞,直到行锁的持有者通过提交或回滚来释放它。

并行 DML 操作和串行插入直接加载操作采用排他表锁。

于 2013-10-31T03:13:49.297 回答