Oracle - Oracle 如何管理特定于事务的 DML 语句

Posted

技术标签:

【中文标题】Oracle - Oracle 如何管理特定于事务的 DML 语句【英文标题】:Oracle - How does Oracle manage transaction specific DML statements 【发布时间】:2011-08-15 18:09:59 【问题描述】:

想象一下我有这个简单的表格:

Table Name: Table1
Columns:    Col1 NUMBER (Primary Key)
            Col2 NUMBER

如果我在没有提交的情况下将记录插入 Table1...

INSERT INTO Table1 (Col1, Col2) Values (100, 1234);

Oracle 如何知道下一个 INSERT 语句违反了 PK 约束,因为尚未向数据库提交任何内容。

INSERT INTO Table1 (Col1, Col2) Values (100, 5678);

Oracle 在何处/如何管理事务,以便在我尚未提交事务时知道我违反了约束。

【问题讨论】:

【参考方案1】:

Oracle 创建一个索引来强制执行主键约束(默认情况下是唯一索引)。当 Session A 插入第一行时,索引结构会更新,但不会提交更改。当会话 B 尝试插入第二行时,索引维护操作注意到索引中已经存在具有该特定键的挂起条目。会话 B 无法获取保护共享索引结构的锁存器,因此它将阻塞直到会话 A 的事务完成。此时,会话 B 将能够获取锁存器并对索引进行自己的修改(因为 A 回滚),或者它会注意到另一个条目已被提交,并将引发唯一约束冲突(因为 A 已提交)。

【讨论】:

Oracle 在哪里/如何管理这个?在某种系统表中? @contactmatt - 在索引结构本身中。就像表的一个块中的每一行都有一个锁标志,这样Oracle就不需要单独的锁管理器,索引块中也有类似的结构。 +1。很好解释。我总是有这个问题要问别人:“这些信息是写在哪里的(索引条目、表条目)?在重做/撤消日志中?” 还有一个问题,当我用插入语句测试我的问题时,它们都在同一个事务和会话中。您通过说明两个不同会话的示例回答了这个问题。同一个会话呢? @contactmatt - 当您在同一个会话中处理多个语句时,它会更容易,因为先前语句所做的更改在同一个事务中是完全可见的。您的第二个插入语句只是访问索引中的适当块(事务已经为其锁定),查看索引中已经存在的数据,然后抛出异常。第二条语句不知道重复行是插入到同一个事务中还是插入到几个月前提交的事务中。【参考方案2】:

这是因为强制主键约束的唯一索引。即使尚未提交对数据块的插入,尝试将重复条目添加到索引中也不会成功,即使它是在另一个会话中完成的。

【讨论】:

我做了一个小测试,确实:第二个事务将等待(锁定),直到您提交或回滚第一个会话。【参考方案3】:

仅仅因为您尚未完成提交并不意味着第一条记录尚未发送到服务器。 Oracle 已经知道您打算插入第一条记录。当您插入第二条记录时,Oracle 肯定知道如果没有违反约束,这将永远不会成功,因此它会拒绝。

如果另一个用户要插入第二条记录,如果第一条记录尚未提交,Oracle 将接受它。如果第二个用户在你之前提交,你的提交将会失败。

【讨论】:

不完全 - 第二个会话挂起,等待第一个事务的结果。试试看。 so it refuses.”是什么意思?是你指的错误信息吗? 我确实尝试过(请参阅我对另一个答案的评论),你是对的:第二个会话挂起,直到第一个会话被提交/回滚。使用 refuse 我预计会违反约束。【参考方案4】:

除非特定约束被“延迟”,否则它将在语句执行时进行检查。如果延迟,将在交易结束时进行检查。我假设你没有推迟你的 PRIMARY KEY,这就是为什么你甚至在你提交之前就被违反了。

如何真正做到这一点是一个实现细节,并且在不同的数据库系统甚至同一系统的版本之间可能会有所不同。应用程序开发人员可能不应该对此做出太多假设。在 Oracle 的案例中,PRIMARY KEY 出于性能原因使用底层索引,而有些系统甚至不需要索引(如果您可以忍受相应的性能损失)。

顺便说一句,可延迟的 Oracle PRIMARY KEY 约束依赖于非唯一索引(与使用唯一索引的不可延迟 PRIMARY KEY 相比)。

--- 编辑 ---

我刚刚意识到您甚至没有提交第一个 INSERT。我认为 Justin 的回答很好地解释了本质上是锁争用如何导致其中一个事务停止。

【讨论】:

以上是关于Oracle - Oracle 如何管理特定于事务的 DML 语句的主要内容,如果未能解决你的问题,请参考以下文章

聚集和非聚集索引 - SQL Server 和 Oracle?

Oracle的表创建和事务管理

oracle 临时表

Oracle在块内是如何组织和管理数据的

管理两个特定于设备的应用程序

如何在 Oracle EBS 中基于表的值集中使用描述性弹性域上下文