【问题标题】:Application becomes unresponsive because of oracle lock由于 oracle 锁,应用程序变得无响应
【发布时间】:2026-01-21 00:20:07
【问题描述】:

应用程序使用官网提供的JDBC驱动连接到oracle 11G数据库。当来自连接到同一架构的不同实例的许多用户(大约 50 个)开始使用该应用程序时,我在应用程序周围遇到了一些冻结,当我运行查询以获取锁定会话和锁定对象时,我发现只有“行独占” lock 类型,通常不应锁定所有表并允许多个会话执行 DML 查询。因此我的问题是行独占表何时可以锁定整个表或引发这些冻结。

注意:我在论坛中查看了一些 MAXTRANS 和 ITL 配置,这些参数会导致这些冻结吗?

谢谢

【问题讨论】:

  • 你说得对,Oracle 中的行锁永远不会升级。您是否正在执行任何 DDL,或使用特定行来保持运行总计或维护序列号......或其他可能需要多个会话修改单行的事情?
  • 是的,我正在使用序列来插入地址表,这是否会导致问题,并且我的所有用户只执行 SELECT/INSERT/UPDATE/DELETE 查询
  • 使用 Oracle 序列对象不会——您当然想检查缓存大小,但不会导致表行锁定。
  • 但是你同意吗,如果我有一个小的 maxtrans 可能低于 50,假设我每个用户都有一个事务,填充 ITL 会导致会话进入等待状态吗?
  • 要诊断出您最好通过等待事件跟踪它们,因为 ITL 等待中的队列会明确显示在那里。

标签: oracle jdbc database-administration table-locking


【解决方案1】:

我认为您的术语混淆了。“行独占”锁定意味着“我已锁定此行。不允许其他会话更新它”。

因此,如果您有 50 个会话都试图更新或删除特定行,那么是的.. 您将有争用。这会严重限制你的表现。

所以我猜您的应用程序可能缺少commit 语句,该语句将在修改行后释放锁。

您说您正在使用序列.. 您是在使用实际的 oracle 序列(即 create sequence my_seq; )还是在自定义诸如 select max(id)+1 from sequence_table 之类的东西,这将是另一个坏主意。

【讨论】:

  • 我使用的是 oracle 序列而不是自定义序列,对于提交部分,是的,我已将 JDBC 驱动程序设置为自动提交每个事务,而且我的用户不会强制更改同一行,但他们正在处理同桌
  • 好吧..那么另一个选择是您的应用代码正在执行类似select * from table for update 的操作并丢弃结果而不是select * from tbale where id = :myid for update
  • 我已经检查了所有查询,但没有一个会错过 where 子句,我知道这样的查询会引发 TM 锁,这就是我首先检查的内容
  • 那么我认为您可能会坚持跟踪会话。对不起
【解决方案2】:

也许现在责怪甲骨文还为时过早。它可以是 servlet 容器配置,例如没有足够的 exec 线程。或者它可能是内部争用。很多事情都可能出错。识别瓶颈的一种快速方法是在应用程序遇到“应用程序周围的一些冻结”时获取线程转储,并查看您的线程卡在哪里。您可以通过向 Java 进程发送 kill -3 来获取线程转储。把它贴在这里,很高兴看到它。

【讨论】:

  • 您好,谢谢您的回答。但我忘了提到这是该应用程序的桌面版本。我正在使用小程序向用户提供内容
  • 没关系。摆脱这种情况的最好方法是确切地知道您的小程序内部发生了什么。如果我是你,我会得到 JProfiler(他们有 2 周的免费评估期)并分析小程序并查看到底发生了什么。除了解决问题之外,您还将获得一项非常有用的技能。
最近更新 更多