Oracle锁基本
锁:是一种资源,是一小块的内存。是为了控制并发中的串行操作。
如果从微观上讲是串行。
锁的类型:
DML 锁
DDL 锁 数据字典锁
内部锁或Latch(mutex)
SQL> select distinct type from v$lock; TY --KD RD AE RT RS CF XR MR PW KT TS
DML锁
TM锁 (表锁) 如果在修改一个表时,如果想删除,则会报资源正在忙
如果是一个基于传统的数据库中,如sql server等,对于行锁定的过程一般如:
1.找到想锁定的一行的地址
2.在锁管理器中排队
3.锁定列表
4.在列表中查找是否已经对这一行进行了锁定
5.如果没有,在列表中创建一个新的条目,表明你已经锁定了这一行。
6.对列表解锁。
解锁过程也是一样。
在oracle中则是 1.直接找到像锁定的哪一行的地址
2.锁定这一行。
oracle中不在使用传统的锁管理器。
TM锁:TM enqueues(队列实现)
命名:<TM-432-0> TM是锁的类型, 432是OBJECT_ID
|
|
如果是一个连接加上了4号S锁。则其他的会话不能修改。
x update 加SX,防止对表进行DDL操作。
LMODE >0 REQUEST =0 OWNER
LMODE =0 REQUEST >0 WAITER(ACQUIRER)
LMODE >0 REQUEST >0 转换
实验:
SQL> select * from lock_t1; ID NAME ---------- ---------------------------------------------------------------------------------------------------- 1 AAAAA 2 BBBBB 3 CCCCC 4 DDDDD 5 EEEEE
先查询出当前的会话
SQL> select sid from v$mystat where rownum=1; SID ---------- 125
执行一个事务
SQL> update lock_t1 set name = 'FFFFF' where id =1; 1 row updated.
ADDR RAW(8) 锁这条记录的地址
KADDR RAW(8) 锁所在的地址。
SID NUMBER SID会话编号
TYPE VARCHAR2(2) 锁的类型
ID1 NUMBER MR 对应的是 file_id TM对应的是object_id
ID2 NUMBER 预留为。
LMODE NUMBER 锁的类型
REQUEST NUMBER 请求锁
CTIME NUMBER 请求的时间(秒)
BLOCK NUMBER 阻塞
SQL> select * from v$lock where sid =125; ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK ---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ---------- 00000000BBCD7600 00000000BBCD7658 125 AE 100 0 4 0 24838 0 00002BA37C8A57A8 00002BA37C8A5808 125 TM 84109 0 3 0 2024 0 00000000B8EBDD50 00000000B8EBDDC8 125 TX 196609 1773 6
196609 ========》4个字节的 16进制 30001 前两位0003 =3,后两个字节0001 1
SQL> select addr,xidusn,xidslot,xidsqn,ubafil from v$transaction; ADDR XIDUSN XIDSLOT XIDSQN UBAFIL ---------------- ---------- ---------- ---------- ---------- 00000000B8EBDD50 3 1 1773 3
可以看出,3,1,1773 = v$transaction中的唯一标记。
在另一个会话中update同一行
SQL> conn cyftest/cyftest Connected. SQL> update lock_t1 set name='tttttt' where id =1;
观察两个结果
SQL> select * from v$lock where sid =125; ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK ---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ---------- 00000000BBCD7600 00000000BBCD7658 125 AE 100 0 4 0 26468 0 00002BA37C8A2700 00002BA37C8A2760 125 TM 84109 0 3 0 3654 0 00000000B8EBDD50 00000000B8EBDDC8 125 TX 196609 1773 6 0
SQL> select * from v$lock where sid =125; ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK ---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ---------- 00000000BBCD7600 00000000BBCD7658 125 AE 100 0 4 0 26587 0 00002BA37C8A57A8 00002BA37C8A5808 125 TM 84109 0 3 0 3773 0 00000000B8EBDD50 00000000B8EBDDC8 125 TX 196609 1773 6 0
block 为1 ,说明阻塞了。