1

如果我在 oracle 中运行一条更新语句,因为它与 where 子句不匹配并且我没有提交,所以它显示“更新了 0 行”,它是否仍会锁定表的任何部分?我的猜测是否定的,但我无法证明。

4

3 回答 3

1

在没有更新任何内容的更新之后不会持有行锁(毕竟,如果没有行,应该锁定哪一个?)

您的事务仍将有一些共享锁(在表上),但这些锁只是为了防止其他事务更改表。它基本上与 select 语句在表上获得的“锁定”类型相同。

从手册

仅当写入者修改时才会锁定行。

并在手册中进一步向下

行锁,也称为 TX 锁,是对单行表的锁。事务为修改的每一行获取一个行锁

因此,如果没有更改任何行,就不可能有锁。

于 2013-09-25T17:02:56.423 回答
0

它不持有任何锁。

简单的测试用例

  1. 打开两个 oracle 会话(sqlplus 或 sqldeveloper 或通过任何其他方式)
  2. 更新 table1 where 子句(会话 1)
  3. 更新 table1 where 子句(会话 2)
  4. 从 session1 提交(如果有表锁,那么这应该挂起)
  5. 从 session2 提交(如果有表锁,则此语句将导致死锁)

条件与行锁定相同(如果存在,两个会话都删除同一行)。

于 2013-09-25T17:03:00.550 回答
0

记载

INSERT、UPDATE、DELETE 和 SELECT ... FOR UPDATE 语句的锁定特性如下:

  • 包含 DML 语句的事务在该语句修改的行上获取排他行锁。在锁定事务提交或回滚之前,其他事务无法更新或删除锁定的行。

  • 包含 DML 语句的事务不需要在子查询或隐式查询(例如 WHERE 子句中的查询)选择的任何行上获取行锁。DML 语句中的子查询或隐式查询保证在查询开始时是一致的,并且看不到它所属的 DML 语句的效果。

  • 事务中的查询可以看到同一个事务中之前的 DML 语句所做的更改,但看不到在它自己的事务之后开始的其他事务的更改。

  • 除了必要的排他行锁之外,包含 DML 语句的事务至少会在包含受影响行的表上获取一个行排他表锁。如果包含事务已持有该表的共享、共享行独占或独占表锁,则不会获取行独占表锁。如果包含事务已经持有行共享表锁,Oracle 数据库会自动将此锁转换为行独占表锁。

表锁对于在更新过程中保护表免受更改是必要的,如果更新没有修改任何行,那么这是唯一应用的锁。

如果语句对一行执行更新,导致该行没有更改(例如,对于 date_of_birth 已经为空的行,SET DATE_OF_BIRTH = NULL,则仍会使用行锁。

于 2013-09-25T17:10:03.467 回答