当前位置: 代码迷 >> Oracle技术 >> INSERT一条语句发作两个锁
  详细解决方案

INSERT一条语句发作两个锁

热度:39   发布时间:2016-04-24 08:11:36.0
INSERT一条语句产生两个锁
CREATE TABLE divisions (
  division_id CHAR(3) CONSTRAINT divisions_pk PRIMARY KEY,
  name VARCHAR2(15) NOT NULL
);
CREATE TABLE jobs (
  job_id CHAR(3) CONSTRAINT jobs_pk PRIMARY KEY,
  name VARCHAR2(20) NOT NULL
);
CREATE TABLE employees2 (
  employee_id INTEGER CONSTRAINT employees2_pk PRIMARY KEY,
  division_id CHAR(3)
    CONSTRAINT employees2_fk_divisions
    REFERENCES divisions(division_id),
  job_id CHAR(3) REFERENCES jobs(job_id),
  first_name VARCHAR2(10) NOT NULL,
  last_name VARCHAR2(10) NOT NULL,
  salary NUMBER(6, 0)
);

我在sqlplus中执行一些INSERT INTO操作,但网络连接中断了,没有commit或rollback。

之后再次sqlplus执行相同的INSERT INTO语句时就hang了,查看锁表的语句:
INSERT INTO divisions (   division_id, name ) VALUES (   'SAL', 'Sales' )
这个就是所有这些INSERT INTO的第一条语句。

使用
SELECT A.USERNAME,
         A.MACHINE,
         A.PROGRAM,
         A.SID,
         A.SERIAL#,
         A.STATUS,
         C.PIECE,
         C.SQL_TEXT
    FROM V$SESSION A,
         V$SQLTEXT C
   WHERE     A.SID IN (SELECT DISTINCT T2.SID
                         FROM V$LOCKED_OBJECT T1,
                              V$SESSION T2
                        WHERE T1.SESSION_ID = T2.SID)
         AND A.SQL_ADDRESS = C.ADDRESS(+)
ORDER BY C.PIECE;
查看:该条INSERT有两个piece:
SID     SERIAL# STATUS  PIECE   SQL_TEXT
200 77 ACTIVE 0 INSERT INTO divisions (   division_id, name ) VALUES (   'SAL', 
200 77 ACTIVE 1 'Sales' )

再用:
SELECT object_id, session_id, locked_mode FROM v$locked_object;
  SELECT t2.username,
         t2.sid,
         t2.serial#,
         t2.logon_time
    FROM v$locked_object t1, v$session t2
   WHERE t1.session_id = t2.sid
ORDER BY t2.logon_time;
查看:
OBJECT_ID SESSION_ID LOCKED_MODE
10271   200      2
10267   200       3

为什么这种情况:
1、INSERT语句会会hang有锁?
2、为什么一条INSERT语句有两个PIECE?
3、为什么一条INSERT语句有两个锁?

谢谢!
------解决方案--------------------
1:insert语句之后没有提交,另外一个进行insert就会产生锁,估计你是没有commit,至于为什么两个Insert会产生锁,去看看Oracle文档和基本的数据库原理的书籍吧
2,3:一个是锁对象,一个是被锁对象

------解决方案--------------------
我来解释下吧:
1、这里谈不上hang住,就是一个简单的锁等待,oracle中,任何dml都会对表或行产生锁,这里应该是行锁等待;    
2、这里的piece,是指代码段的意思,就是一条语句,拆分为多个piece,具体你可以看看V$SQLTEXT视图的定义;
3、这里你查出的,应该是被锁的对象,也就是表,而不是锁。在你的会话里,因为执行了多个insert语句,这些insert语句会涉及到两个表的操作,这两个表的object_id分别为:10271,10267,你可以通过user_objects去查询这两个被锁的对象。
  相关解决方案