偶现在维护的系统中, 排他处理的做法是,想独占打开一条(或多条)记录时就用SELECT ... FOR UPDATE NOWAIT, 捕获到排他的异常就报个数据正在使用的错误.现在客户希望知道具体是谁锁定了自己要使用的数据(能报出机器名或OS的用户名都行)哪位实现过类似的功能,能否指点一下? DB是ORACLE 10G, 用OO4O连接--考虑过用遍历v$locked_object的方法, 如果所有的锁都是表级别锁的话,应该可行,但现在我们系统里很多都是行级别锁,用户A锁记录1,用户B锁记录2,用户C想编辑记录2时,v$locked_object里两条记录都满足条件,如果报出A用户在使用的话,就是冤假错案了...

解决方案 »

  1.   

    加了nowait难。如不加nowait,从v$lock中的ID1和ID2字段,能看出具体请求的行
    1 07000001DD305AC8 07000001DD305AE8 132 TX 1441799 66062 0 6 79 0
    2 07000001E0E7CD30 07000001E0E7CEA8 340 TX 2228256 40737 6 0 289 0
    3 07000001DEF8EB00 07000001DEF8EC78 547 TX 1441799 66062 6 0 382 1
    如132和547请求是同一行,所以132被阻塞了,但加了nowait后,实际上看不到这个信息了。
    除非知道1441799 66062具体是哪一行,以及你请求的是哪一行
      

  2.   

    哦,楼上说的是利用v$lock里等待记录的BLOCK标志是吧...
    这系统里现在都是用的NOWAIT,这招估计行不通了...我越来越发觉这是个不可能的任务了,除非象返回执行SQL的ERRCODE一样,有一个直接就能返回来的跟LOCK相关的信息,否则估计很难了...
      

  3.   

    为什么这功能不放在应用层去做呢,晕,什么都往数据层整。除非是作数据仓库的数据库系统可以有比较繁琐的计算功能,我觉得OLTP中数据库尽量只做数据存储,不然太伤害数据库服务器的性能,将这些复杂的功能都可以放在应用层,如果应用层支撑不住了,做个负载均衡就OK,但是要将数据库作负载均衡,那成本就大了
      

  4.   

    网上FAQ中搜到一样的问题,某牛人回复说这是不可能的,哎原贴地址
    http://www.orafaq.com/maillist/oracle-l/2001/02/01/0185.htm既然没法准确定位, 只能把当前系统中所有跟当前SQL相关的锁定信息以列表形式显示出来,让客户自己猜去吧...此贴再挂几天,周末结了...
      

  5.   

    你这个是个业务上的长事务,如果使用数据库的事务处理,我想太伤害数据库性能了吧.比如从数据库中读取某条记录并修改其数据,读的时候使用for update锁定该行,然后用户编辑时一直锁定,直到用户修改完成提交事务,这个事务太长了.为什么不在应用才层做呢.读取一条记录以后在数据库写一个状态,提交时更改这个状态.