现有多台机器的客户端访问同一数据库,在A打开对话框编辑表的时候锁定表,
如何B也要编辑这个表,他会得到一个提示某人正在编辑,直到A关闭对话框。
请问方式比较好,乐观锁 or 悲观锁?
如果A非正常退出,他所操作的表还未解锁该怎么处理了?谢谢

解决方案 »

  1.   

    --查锁:
    SELECT /*+ rule */ s.username, 
    decode(l.type,'TM','TABLE LOCK', 
                  'TX','ROW LOCK', 
                  NULL) LOCK_LEVEL, 
    o.owner,o.object_name,o.object_type, 
    s.sid,s.serial#,s.terminal,s.machine,s.program,s.osuser 
    FROM v$session s,v$lock l,dba_objects o 
    WHERE l.sid = s.sid 
    AND l.id1 = o.object_id(+) 
    AND s.username is NOT NULL--杀掉会话:
    alter system kill session 'sid,serial#';
      

  2.   

    编辑对话框显示了某个表的内容,修改后点保存,否则不处理。
    对话框打开的时候我用select * from ss for update nowait,
    关闭对话框的时候commit。
    如何对话框没有关闭的情况下,我用任务管理器结束进程,这个表是不是还在锁定状态呢?
      

  3.   

    开两个sqlplus, 以scott登录:A执行:
    update dept set loc = 'AAA';B执行:
    update dept set loc = 'AAA';然后不提交关掉A, 
    B窗口出现假死状况, 此时可以查到系统被锁定的对象:SQL> select * from v$locked_object;
     
        XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME                OS_USER_NAME                   PROCESS      LOCKED_MODE
    ---------- ---------- ---------- ---------- ---------- ------------------------------ ------------------------------ ------------ -----------
             3         47      10005      51209        130 SCOTT                          leipc                          5876:2664              3
             0          0          0      51209        144 SCOTT                          leipc                          5108:2824              3
      

  4.   

    然后kill那个崩溃的session就可以了
    SQL> select SID, SERIAL#, USERNAME from v$session where username = 'SCOTT';
     
           SID    SERIAL# USERNAME
    ---------- ---------- ------------------------------
           130        118 SCOTT
           144        209 SCOTTSQL> alter system kill session '130,118';
     
    System altered这样, B窗口的假死状态消失,执行结果出现:
    SQL> update dept set loc = 'AAA';4 rows updated.
      

  5.   


    这个要调整数据库的设置
    如果一个连接长时间inactive, 就将其回收剩下的工作oracle会帮你做
      

  6.   

    谢谢两位的回复,
    怎么判断session是非正常结束了?
      

  7.   

    流程这样写,你看行不行?
    1.打开编辑对话框,查询是否有非正常结束的session,若有则kill,
      然后select * from table1 for update nowait,如果返回错误,则提示
      用户有人在编辑。
    2.关闭对话框时commit,解锁。
      

  8.   

    非正常结束就是exception, 你可以捕捉到
    然后根据不同的情况作处理你如果一定要把kill写到程序流程里, 
    那么注意kill的方式, 暴力的kill需要很长时间才能释放资源, 这个egyle早有文章讨论过, 建议看一看:
    http://www.eygle.com/faq/Kill_Session.htm如果只是要处理一个并发写的问题,
    那么在相关的流程中select for update nowait就可以了,
    成功则提交, 不成功则回滚 
      

  9.   

    我用的是oracle express edition,
    用IE登陆后打开两个sql command tab页,执行select * from account for update,
    为什么都能执行,第二个tap页执行时不是应该提示锁定错误吗?谢谢