lock
_sys@FAKE>@lock2
OBJECT_NAME SID TYPE ID1 LMODE REQUEST BLOCK
---------------------------------------- ---- ---------- ---------- ---------- ----------
TUN2_P 9 TM 82949 3 0 0
9TX 655390 6 0 0
TUN2_C 9 TM 82952 3 0 0
子表删除
_dexter@FAKE>delete from tun2_c where pid=1 ;
2 rowsdeleted.
lock:
_sys@FAKE>@lock2
OBJECT_NAME SID TYPE ID1 LMODE REQUEST BLOCK
---------------------------------------- ---- ---------- ---------- ---------- ----------
TUN2_P 9 TM 82949 3 0 0
9TX 196635 6 0 0
TUN2_C 9 TM 82952 3 0 0
子表的记录一定会引用到父表的记录,所以在对子表进行dml操作的时候,都会锁定父表。
复杂示例
两个表中现在么有任何记录。
session1 session_id=9:
_dexter@FAKE>insert into tun2_p values (1) ;
1 rowcreated.
看一下锁的情况:
_sys@FAKE>@lock2
OBJECT_NAME SID TYPE ID1 LMODE REQUEST BLOCK
---------------------------------------- ---- ---------- ---------- ---------- ----------
TUN2_C 9 TM 82952 3 0 0
TUN2_P 9 TM 82949 3 0 0
9TX 262149 6 0 0
可以看到,当向父表中插入记录的时候,会同时锁定父表和子表,加表的3级共享锁。
session1没提交之前其他事务无法看到父表中的id=1的记录,我们再来尝试一下向子表中插入pid=1的记录
session2 session_id=18:
_dexter@FAKE>insert into tun2_c values (1) ;
waiting ...
可以看到session2 进入了阻塞状态,我们来查看一下锁的情况
_sys@FAKE>@lock2
OBJECT_NAME SID TYPE ID1 LMODE REQUEST BLOCK
---------------------------------------- ---- ---------- ---------- ---------- ----------
TUN2_C 9 TM 82952 3 0 0
9TX 262149 6 0 1
TUN2_P 9 TM 82949 3 0 0
18TX 262149 0 4 0
TUN2_C 18 TM 82952 3 0 0
18TX 589848 6 0 0
TUN2_P 18 TM 82949 3 0 0
7 rowsselected.
首先我们可以看到,session2也有两个TM表锁,分别锁定了子表和父表。这说明在子表更新数据的时候,也会对引用的对象加锁。
然后我们还看到,子表陷入了等待当中。
这是因为session2 中的事务是否能够成功执行,取决于session1 中的事务状态。而session1 中的事务现在是悬而未决的状态。
是不是有点和读一致性搞混了?觉得第二个session中的事务不应该进入阻塞当中,而是直接报错?
它不像读一致性,可以在查询的时候根据undo获取一个一致性视图。
在事务执行的时候,只和数据的当前状态相关。
第一个session的事务rollback后
session2就会报错
_dexter@FAKE>insert into tun2_c values (1) ;
insert intotun2_c values (1)
*
ERROR atline 1:
ORA-02291:integrity constraint (DEXTER.SYS_C0014143) violated - parent key not found
|
|
Session1 |
Session2 |
Description |
| T1 |
insert into tun2_c values (1) ; |
|
|
| T2 |
|
insert into tun2_c values (1) ; waiting… |
正常理解,这里应该直接报错,ORA-02291才对,但是这里没有,因为父表中id=1的记录还是悬而未决的状态。这是智能呢?还是智能呢?还是智能呢?那就是智能吧。 |
| T3 |
rollback |
|
|
| T4 |
|
Raise error ORA-02291: integrity constraint (DEXTER.SYS_C0014143) violated - parent key not found |
一切都明了了,报错了。 |
3.从mode 2-6 的TM锁相互间的互斥示例。
再次引用这张表
|
|
RS|SS |
RX|SX |
S |
SRX|SSX |
X |
| RS|SS |
√ |
√ |
√ |
√ |
× |
| RX|SX |
√ |
√ |
× |
× |
× |
| S |
√ |
× |
√ |
× |
× |
| SRX|SSX |
√ |
× |
× |
× |
× |
| X |
× |
× |
× |
× |
× |
介绍一些操作
| lock table tun2_tab in ROW SHARE mode ; |
lmode=2 |
| lock table tun2_tab in ROW EXCLUSIVE mode ; |
lmode=3 |
| lock table tun2_tab in SHARE MODE ; |
lmode=4 |
| lock table tun2_tab in SHARE ROW EXCLUSIVE MODE ; |
lmode=5 |
| lock table tun2_tab in EXCLUSIVE MODE ; |
lmode=6 |
下面的示例演示验证上表的内容
Row Share (RS)
Also called a subshare table lock (SS)
Session1 session_id=35 :
dexter@STARTREK>create table tun2_tab (x int) ;
Tablecreated.
dexter@STARTREK>lock table tun2_tab in ROW SHARE mode nowait ;
Table(s)Locked.
session2 session_id=160:
dexter@STARTREK>lock table tun2_tab in ROW SHARE mode ;
Table(s)Locked.
dexter@STARTREK>commit ;
Commitcomplete.
dexter@STARTREK>lock table tun2_tab in ROW EXCLUSIVE mode ;
Table(s)Locked.
dexter@STARTREK>commit ;
Commitcomplete.
dexter@STARTREK>lock table tun2_tab in SHARE MODE ;
Table(s)Locked.
dexter@STARTREK>commit ;
Commitcomplete.
dexter@STARTREK>lock t