分类: Oracle
2008-04-11 10:14:35
来源:赛迪网 作者:Alice |
这时,如果SESS#1进行回滚:
SESS#1 SQL> ROLLBACK;
Rollback complete.
SESS#2
1 row created.
SESS#3
SQL> @showlock
O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN
---------- ----- --------------- --------------- ------ ------- ------
SCOTT 8 Row Exclusive DEPT 7 75 30
SQL> @showalllock
SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK
----- -- ---------- ---------- --------------- ---------- ---------- ----------
8 TX 458827 30 Exclusive 0 136 0
8 TM 3574 0 Row Exclusive 0 136 0
SESS#2的阻塞将被解除, SESS#2 只持有原先已有的TM与TX 锁,其等待的TX 锁(由
SESS#1持有)也消失了。
如果SESS#1提交而不是回滚,在 SESS#2上将会出现如下提示:
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.PK_DEPT) violated 错误。
即发生主键冲突,SESS#1与SESS#2 的所有锁资源均被释放。
4.3 参照完整性引发的锁阻塞
EMP(员工)表有如下字段:EMPNO(员工编号),ENAME(员工姓名),DEPTNO
(员工所在部门编号),其中 DEPTNO 列为外键,其父表为 DEPT。
SESS#1
SQL> insert into dept(deptno) values(60);
1 row created.
SESS#3
SQL> @showlock
O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN
---------- ----- --------------- --------------- ------ ------- ------
SCOTT 7 Row Exclusive DEPT 2 6 33
SQL> @showalllock
SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK
----- -- ---------- ---------- --------------- ---------- ---------- ----------
7 TX 131078 33 Exclusive 0 148 0
7 TM 3574 0 Row Exclusive 0 148 0
SESS#1(SID 为 7)在 DEPT 表中先插入一条 DEPTNO 为 60 的记录,SESS#1 获得了
DEPT表上的Row Exclusive 锁,及一个TX锁。
SESS#2
insert into emp(empno,deptno) values(2000,60);
被阻塞
SESS#3 SQL> @showlock
O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN
---------- ----- --------------- --------------- ------ ------- ------
SCOTT 7 Row Exclusive DEPT 2 6 33
SCOTT 8 Row Exclusive EMP 3 20 31
SQL> @showalllock
SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK
----- -- ---------- ---------- --------------- ---------- ---------- ----------
7 TX 131078 33 Exclusive 0 228 1
7 TM 3574 0 Row Exclusive 0 228 0
8 TX 196628 31 Exclusive 0 9 0
8 TM 3576 0 Row Exclusive 0 9 0
8 TX 131078 33 None 4 9 0
SESS#2(SID 为 8)向 EMP 表中出入一条新记录,该记录 DEPT 值为 60(即 SESS#1
刚插入,但还未提交的记录的DEPTNO值), SESS#2 获得了EMP 表上的Row Exclusive 锁,
另外由于插入记录,还分配了回滚段及一个TX 锁,但由于 SESS#2 的插入语句是否成功取
决于SESS#1的事务是否进行提交,所以它被阻塞,表现为 SESS#2 以Share(REQUEST=4)
方式等待SESS#1释放其持有的 TX锁。这时SESS#1 如果提交,SESS#2的插入也将执行成
功,而如果SESS#1 回滚,由于不符合参照完整性,SESS#2 将报错:
SESS#2
insert into emp(empno,deptno) values(2000,60)
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not
Found
SESS#2持有的锁也被全部释放。
4.4 外键未加索引引发的锁阻塞
EMP 表上的DEPTNO 列为外键,但没有在该列上建索引。
SESS#1
SQL> delete emp where 0=1;
0 rows deleted.
SESS#3:
SQL> @showlock
O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN
---------- ----- --------------- --------------- ------ ------- ------
SCOTT 7 Row Exclusive EMP 0 0 0
SQL> @showalllock
SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK
----- -- ---------- ---------- --------------- ---------- ---------- ----------
7 TM 3576 0 Row Exclusive 0 10 0
首先SESS#1(SID为7)做了一个删除操作,但由于条件(0=1)为永假,所以实际上
并没有一行被删除,从监控脚本可以看出SESS#1在 EMP 表上获得Row Exclusive 锁,但由于没有实际的行被删除,所以并没有TX锁,也没有为 SESS#1分配回滚段。
SESS#2:
SQL> delete dept where 0=1;
该语句虽然也不会删除实际数据,但却被阻塞,查看系统的锁情况: |