首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何排除enq: TX -行锁争用?

如何排除enq: TX -行锁争用?
EN

Database Administration用户
提问于 2012-05-30 10:05:53
回答 2查看 84.1K关注 0票数 10

我有以下情况。

我有RAC。在两个节点上都有锁。

关于第一个节点的

代码语言:javascript
复制
    SID EVENT                           USERNAME    BLOCKING_SESSION    ROW_WAIT_OBJ#   OBJECT_NAME LOCKWAIT            SQL_ID          STATUS
1   102 enq: TX - row lock contention   MYUSER      155                 136972          TABLE1V     0000000810EFA958    5f4bzdg49fdxq   ACTIVE
2   111 enq: TX - row lock contention   MYUSER      155                 136972          TABLE1V     0000000810EFAC98    5f4bzdg49fdxq   ACTIVE

阻塞会话信息

代码语言:javascript
复制
    SID EVENT                       USERNAME    ROW_WAIT_OBJ#   OBJECT_NAME LOCKWAIT    SQL_ID          STATUS
1   155 SQL*Net message from client MYUSER      136971          MyTABLEIMAGES_IDPK      4hw85z8absbjc   INACTIVE

关于第二节点的

代码语言:javascript
复制
    SID EVENT                           USERNAME    BLOCKING_SESSION    ROW_WAIT_OBJ#   OBJECT_NAME   LOCKWAIT          SQL_ID          STATUS
1   65  enq: TX - row lock contention   MYUSER      155                 137033          FactTABLE1V   0000000810EF9B58  1mznc2z75ksdx   ACTIVE
2   111 enq: TX - row lock contention   MYUSER      155                 136972          TABLE1V       0000000810EF9818  5f4bzdg49fdxq   ACTIVE

阻塞会话信息

代码语言:javascript
复制
    SID EVENT                       USERNAME    ROW_WAIT_OBJ#   OBJECT_NAME  SQL_ID  STATUS
1   155 SQL*Net message from client MYUSER      127176          MYTableLOG           INACTIVE

附加信息:阻塞会话SQL_TEXT

代码语言:javascript
复制
create or replace procedure ACTIONProcedureDELETE
(
p_ID NUMBER
)
 is

 cursor oldval is select r.id,r.sessionstatus
  from MyTABLEIMAGES  r where r.idparent=p_ID;

begin
       update  actionmyTableblock r  set r.status='False' where  ID=p_ID;

   for oldvalItem in oldval loop

    if oldvalItem.Sessionstatus='True' then
      update MyTABLEIMAGES r set r.sessionstatus='False' where r.id=oldvalItem.Id;
    else
      update MyTABLEIMAGES r set r.sessionstatus='True' where r.id=oldvalItem.Id;
    end if;
  end loop;

end ACTIONProcedureDELETE;

如何解决这个问题?

如您所见,阻塞会话是不活动的,但仍然是锁定的。

如果我select v$sql_bind_capture,则VALUE_STRING没有阻止会话sql_id的值。

从哪里开始?

我可以猜到这里缺少提交/回滚,但是应用程序开发人员说:“我拥有一切,我已经在必要的地方编写了提交。”

请帮帮忙。

EN

回答 2

Database Administration用户

发布于 2012-05-31 12:57:31

您可以避免行锁争用,方法是确保行可以预先使用SELECT FOR UPDATEWAIT XNOWAIT进行更新,例如:

代码语言:javascript
复制
create or replace procedure ACTIONProcedureDELETE (p_ID NUMBER)
 is

 cursor oldval is select r.id,r.sessionstatus
  from MyTABLEIMAGES  r where r.idparent=p_ID FOR UPDATE NOWAIT;

 l_id NUMBER;

begin
   select id into l_id from actionmyTableblock where ID=p_ID 
      FOR UPDATE of status NOWAIT;

   update  actionmyTableblock r  set r.status='False' where  ID=p_ID;

   for oldvalItem in oldval loop

    if oldvalItem.Sessionstatus='True' then
      update MyTABLEIMAGES r set r.sessionstatus='False' where r.id=oldvalItem.Id;
    else
      update MyTABLEIMAGES r set r.sessionstatus='True' where r.id=oldvalItem.Id;
    end if;
  end loop;

end ACTIONProcedureDELETE;

如果该行被锁定,您将收到ORA-00054,这在大多数情况下比无限期等待要好。

票数 6
EN

Database Administration用户

发布于 2019-06-02 11:54:20

您可以使用select for update跳转锁定,这样更优雅和更安全。

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/18569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档