zoukankan      html  css  js  c++  java
  • oracle学习----行级锁的理解

    通过实验来理解行级锁的发生

    1.创建需要的表

    SQL> conn / as sysdba
    已连接。
    SQL> create table dept as select * from scott.dept;

    表已创建。

    SQL> create table emp as select * from scott.emp;

    表已创建。

    SQL> alter table dept add constraint dept_pk primary key(deptno);

    表已更改。

    SQL> alter table emp add constraint emp_pk primary key(empno);

    表已更改。

    SQL> alter table emp add constraint emp_fk_dept foreign key(deptno) references dept(deptno);

    表已更改。

    SQL> create index emp_deptno_idx on emp(deptno);

    索引已创建。

    2.执行更新操作

    SQL> update dept set dname=initcap(dname);

    已更新4行。

    3.查看此时的系统状态

    SQL> set linesize 200 pagesize 1000
    SQL> select username,
    2 v$lock.sid,
    3 trunc(id1/power(2,16)) rbs,
    4 bitand(id1,to_number('ffff','xxxx'))+0 slot,
    5 id2 seq,
    6 lmode,
    7 request
    8 from v$lock,v$session
    9 where v$lock.type='TX'
    10 and v$lock.sid=v$session.sid
    11 and v$session.username=USER;

             USERNAME      SID    RBS     SLOT    SEQ     LMODE  REQUEST
    ------------------------------ ---------- ---------- ---------- ---------- ---------- ----------
                SYS     68      3      23     898      6      0  

    通过列表可以看出lmode=6是排它锁,request=0代表没有锁请求,就是说更新了表的数据没有另一个会话更新同一条数据,就没有锁请求

    SQL> select XIDUSN,XIDSLOT,XIDSQN from v$transaction;查出来的信息是事务ID可以和查询出的锁信息相对应。

    XIDUSN     XIDSLOT  XIDSQN
    ---------- ---------- ----------
    3                        23         898

    4.在一个新的会话中登录相同的用户,执行更新操作

    SQL> update emp set ename=upper(ename);

    已更新14行。

    SQL> update dept set deptno=deptno-10;

    5.查看系统信息

    SQL> select username,
    2 v$lock.sid,
    3 trunc(id1/power(2,16)) rbs,
    4 bitand(id1,to_number('ffff','xxxx'))+0 slot,
    5 id2 seq,
    6 lmode,
    7 request
    8 from v$lock,v$session
    9 where v$lock.type='TX'
    10 and v$lock.sid=v$session.sid
    11 and v$session.username=USER;

    USERNAME SID RBS SLOT SEQ LMODE REQUEST
    ------------------------------ ---------- ---------- ---------- ---------- ---------- ----------
    SYS 130 3 23 898 0 6
    SYS 68 3 23 898 6 0 
    SYS 130 5 33 872 6 0

    SQL> select XIDUSN,XIDSLOT,XIDSQN from v$transaction;

    XIDUSN XIDSLOT XIDSQN
    ---------- ---------- ----------
    3 23 898---第一次
    5 33 872---第二次

    在事务信息中多了一条,在锁的信息中多了两条,其中一条请求为排他锁6,他的rbs/slot/seq与第一次的相同,说明给他加锁的就是第一次的更新操作,他在请求这个锁,来获得资源,在第二个会话中第一条语句由于也没有提交所以他也出现了排它锁。

    通过锁的自联结就可以更清楚的看出他们之间谁锁了谁
    SQL> select
    2 (select username from v$session where sid=a.sid) blocker,
    3 a.sid,
    4 'is blocking',
    5 (select username from v$session where sid=b.sid) blockee,
    6 b.sid
    7 from v$lock a,v$lock b
    8 where a.block=1
    9 and b.request >0
    10 and a.id1=b.id1
    11 and a.id2=b.id2;

    BLOCKER SID 'ISBLOCKING BLOCKEE SID
    ------------------------------ ---------- ----------- ------------------------------ ----------
    SYS 68 is blocking SYS 130

    6.提交事务,查询锁信息

    SQL> commit;

    提交完成。

    SQL> select username,
    2 v$lock.sid,
    3 trunc(id1/power(2,16)) rbs,
    4 bitand(id1,to_number('ffff','xxxx'))+0 slot,
    5 id2 seq,
    6 lmode,
    7 request
    8 from v$lock,v$session
    9 where v$lock.type='TX'
    10 and v$lock.sid=v$session.sid
    11 and v$session.username=USER;

    USERNAME SID RBS SLOT SEQ LMODE REQUEST
    ------------------------------ ---------- ---------- ---------- ---------- ---------- ----------
    SYS 130 5 33 872 6 0

    SQL> select XIDUSN,XIDSLOT,XIDSQN from v$transaction;

    XIDUSN XIDSLOT XIDSQN
    ---------- ---------- ----------
    5 33 872

    SID为68的锁不见了,130的锁只剩下了一个,有锁请求的信息也消失了,这就解释了oracle的锁机制,首先oracle的行锁不会使用锁队列管理,在第二个会话中有两个更新操作没有提交,如果是队列管理应该会有两个锁信息,现在只有一个,那在第一个会话没有提交的时侯出现两个锁信息,是因为第一个会话更新的时候对行加了排它锁,第二个会话想更新相同的行,就要向会话一发出锁请求,所以在锁信息里才有它的出现,但是它的出现,他的模式是0这样就可以理解了。

    相关 脚本总结

    查询锁得相关信息

    查询当前会话的操作的锁状态

    select username,
    v$lock.sid,
    trunc(id1/power(2,16)) rbs,
    bitand(id1,to_number('ffff','xxxx'))+0 slot,
    id2 seq,
    lmode,
    request
    from v$lock,v$session
    where v$lock.type='TX'
    and v$lock.sid=v$session.sid
    and v$session.username=USER;

    在事务视图中找到相应的对照信息

    select XIDUSN,XIDSLOT,XIDSQN from v$transaction;

    查看锁的自联结信息,可以查看谁把谁锁定了

    select
    (select username from v$session where sid=a.sid) blocker,
    a.sid,
    'is blocking',
    (select username from v$session where sid=b.sid) blockee,
    b.sid
    from v$lock a,v$lock b
    where a.block=1
    and b.request >0
    and a.id1=b.id1
    and a.id2=b.id2;

  • 相关阅读:
    shell 格式化输出
    Linux tar 修改终端命令
    uniqu 用法
    HashMap按照value值进行排序
    汇编语言系列教程之基础入门 (一)
    Linux权限管理
    linux用户管理
    vim的tab键设定
    HTTP请求(GET与POST区别)和响应
    JS eval()
  • 原文地址:https://www.cnblogs.com/SUN-PH/p/4155797.html
Copyright © 2011-2022 走看看