我正在使用oracle 11g数据库,而且我遇到了锁定问题。
我有2个会话,我按如下方式执行:
在两个存储过程(插入和更新)中,我包含以下子句:
LOCK TABLE table1 IN ROW EXCLUSIVE MODE;
我认为问题在于oracle正在插入一个表锁,或者它只是没有得到我正在尝试更新的行,虽然,不是行级表锁的目标??
提前感谢您的帮助!
我的剧本:
CRETE TABLE
CREATE TABLE ARGOXP.T_AREA
(
ARE_ID INTEGER,
ARE_NOMBRE VARCHAR2(80 BYTE) NOT NULL,
ARE_DESCRI VARCHAR2(1000 BYTE),
ARE_ACTIVO NUMBER(1) NOT NULL
)
TABLESPACE ARGOXP
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX ARGOXP.PK_T_AREA ON ARGOXP.T_AREA
(ARE_ID)
LOGGING
TABLESPACE ARGOXP
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOPARALLEL;
CREATE UNIQUE INDEX ARGOXP.UK_ARE_NOMBRE ON ARGOXP.T_AREA
(ARE_NOMBRE)
LOGGING
TABLESPACE ARGOXP
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOPARALLEL;
ALTER TABLE ARGOXP.T_AREA ADD (
CONSTRAINT PK_T_AREA
PRIMARY KEY
(ARE_ID)
USING INDEX
TABLESPACE ARGOXP
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
),
CONSTRAINT UK_ARE_NOMBRE
UNIQUE (ARE_NOMBRE)
USING INDEX
TABLESPACE ARGOXP
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL
64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
));
商店程序
CREATE OR REPLACE PROCEDURE ARGOXP."P_T_AREA_I_PK"
(
pARE_ID T_AREA.ARE_ID%TYPE,
pARE_NOMBRE T_AREA.ARE_NOMBRE%TYPE,
pARE_DESCRI T_AREA.ARE_DESCRI%TYPE := NULL,
pARE_ACTIVO T_AREA.ARE_ACTIVO%TYPE
)
AS
BEGIN
LOCK TABLE T_AREA IN ROW EXCLUSIVE MODE;
INSERT INTO T_AREA
( ARE_ID,
ARE_NOMBRE,
ARE_DESCRI,
ARE_ACTIVO
)
VALUES
( pARE_ID,
pARE_NOMBRE,
pARE_DESCRI,
pARE_ACTIVO
);
END;
/
CREATE OR REPLACE PROCEDURE ARGOXP."P_T_AREA_U_PK"
(
pARE_ID T_AREA.ARE_ID%TYPE,
pARE_NOMBRE T_AREA.ARE_NOMBRE%TYPE,
pARE_DESCRI T_AREA.ARE_DESCRI%TYPE := NULL,
pARE_ACTIVO T_AREA.ARE_ACTIVO%TYPE
)
AS
BEGIN
LOCK TABLE T_AREA IN ROW EXCLUSIVE MODE;
UPDATE
T_AREA
SET
ARE_ID = pARE_ID,
ARE_NOMBRE = pARE_NOMBRE,
ARE_DESCRI = pARE_DESCRI,
ARE_ACTIVO = pARE_ACTIVO
WHERE
ARE_ID = pARE_ID
;
END;
/
最新更新
我们最近几天一直在努力解决这个问题,我们希望分享最新的更新。我们在不使用存储过程的情况下在2个会话中执行插入和更新,这导致非锁定。之后,我们为插入和更新创建了新的存储过程,没有参数。我们只包含存储过程定义和脚本来执行插入或更新。这导致非锁定!但是当我们用参数调用存储过程时,我们得到了锁。
我按照执行步骤来获取锁定:
(FIRST) 在第1场会议中:
DECLARE
PARE_ID NUMBER;
PARE_NOMBRE VARCHAR2(80);
PARE_DESCRI VARCHAR2(1000);
PARE_ACTIVO NUMBER;
BEGIN
PARE_ID := 70;
PARE_NOMBRE := '70';
PARE_DESCRI := '70';
PARE_ACTIVO := 1;
ARGOXP.P_T_AREA_I_PK ( PARE_ID, PARE_NOMBRE, PARE_DESCRI, PARE_ACTIVO );
END;
(第二) 在第2场会议
DECLARE
PARE_ID NUMBER;
PARE_NOMBRE VARCHAR2(80);
PARE_DESCRI VARCHAR2(1000);
PARE_ACTIVO NUMBER;
BEGIN
PARE_ID := 71;
PARE_NOMBRE := '71';
PARE_DESCRI := '71';
PARE_ACTIVO := 1;
ARGOXP.P_T_AREA_I_PK ( PARE_ID, PARE_NOMBRE, PARE_DESCRI, PARE_ACTIVO );
END;
(第三)在第二场会议
DECLARE
PARE_ID NUMBER;
PARE_NOMBRE VARCHAR2(80);
PARE_DESCRI VARCHAR2(1000);
PARE_ACTIVO NUMBER;
BEGIN
PARE_ID := 1;
PARE_NOMBRE := 'update number 1';
PARE_DESCRI := 'update number 2';
PARE_ACTIVO := 1;
ARGOXP.P_T_AREA_U_PK ( PARE_ID, PARE_NOMBRE, PARE_DESCRI, PARE_ACTIVO );
END;
我们在这一步中得到了锁。
我们还使用sysdba用户执行以下查询:
SELECT b.OBJECT_NAME, c.ROW_WAIT_OBJ#,c.ROW_WAIT_FILE#,c.ROW_WAIT_BLOCK#,c.ROW_WAIT_ROW#
FROM v$locked_object a, dba_objects b, v$session c
WHERE a.object_id = b.object_id
AND a.SESSION_ID = c.sid(+);
获得以下结果:
答案 0 :(得分:1)
我们发现了问题。我们有另一个表TABLE_2,它引用了表T_AREA(名为AREA_ID的外键字段)。当我们有一个外键但我们在该表中没有索引时,oracle会自动锁定整个表。
因此,解决方案是在TABLE_2中为FK字段添加索引(在本例中为ARE_ID)