UPDATE GJZB SET KEYWORD=(SELECT LPAD(TO_CHAR(To_NUMBER(KEYWORD)+1),KEYLONG,'0') FROM GJZB WHERE UPPER(TABLENAME)=UPPER(STR_TABLENAME)) WHERE UPPER(TABLENAME)=UPPER(STR_TABLENAME);

解决方案 »

  1.   


     看来你还不太了解oracle 的锁定机制 ... 并发操作时,存储过程中必须加行锁,操作完成后尽快提交事务。
      

  2.   

    UPDATE GJZB SET KEYWORD=(SELECT LPAD(TO_CHAR(To_NUMBER(KEYWORD)+1),KEYLONG,'0') FROM GJZB WHERE UPPER(TABLENAME)=UPPER(STR_TABLENAME)) AND UPPER(TABLENAME)=UPPER(STR_TABLENAME);问题不在这儿,而是表GJZB的tab_rsda_jcxx这一行被锁住,用其他的数据库操作软件都不能进行update这一行的数据了,但其他行可以!
      

  3.   

    SELECT KEYWORD,KEYLONG INTO STR_OLDKEY,KEYLENGTH FROM GJZB WHERE UPPER(TABLENAME)=UPPER(STR_TABLENAME) for update;
      

  4.   

    to: leecooper0918(帮助别人,其实也是在帮助自己)请教一下,对于我这个存储过程,应该加什么进行防止并发情况的出现?谢谢了!
      

  5.   

    SELECT KEYWORD,KEYLONG INTO STR_OLDKEY,KEYLENGTH FROM GJZB WHERE UPPER(TABLENAME)=UPPER(STR_TABLENAME) for update;
    ...
    ...
    ...
    commit;--------------------------------
    这样就自动枷锁自动解锁了,当然如果出现异常,建议通过dbms_transaction包做事务处理;
      dbms_transaction.savepoint;
      dbms_transaction.commit;
      dbms_transaction.rollback;
      

  6.   


     问题不在这儿,而是表GJZB的tab_rsda_jcxx这一行被锁住,用其他的数据库操作软件都不能进行update这一行的数据了,但其他行可以!
    --------------------------------------
     这就是oracle的锁定机制,以防止多个会话同时修改表中的同一行。 基本概念:
         修改操作时,Oracle 引发行锁定, 它不会升级为块锁定,表锁定;     不会为了读取数据而使用锁定, 简单的读操作不会引发行锁定 ;
     
         数据写不会阻碍数据读。让我再重复一次: 数据读不会被数据写
         阻碍。在这点上Oracle 与其他大多数数据库存在根本差异;
       
         只有在数据行已经被其他写操作锁定时,才会阻碍另一个数据写
         操作。
      

  7.   

    to:sanoul(垃圾) 
    你的意思就是在我根据参数tablename读取keyword时的sql语句后加:FOR UPDATE即可以实现自动加锁和自动解锁?请详细说明一下,俺对oracle还处于不是很了解的状态,谢谢~~
      

  8.   

    不错,就是在你的select 后面加上for update就可以了,其他照旧
      

  9.   

    我怎样才能知道数据库在update这一行时已经发生的异常?是不是有参数?这样我就可以执行异常操作,
    dbms_transaction.savepoint;
      dbms_transaction.commit;
      dbms_transaction.rollback;
    上面这三行可以直接加到我的存储过程中去吗?
      

  10.   

    select * from tablename for update;//for update 是行级加锁lock table tablename in exclusive MODE;//lock 是表级加锁,in exclusive mode表明加锁机制是独占方式
      

  11.   

    你的功能无非是通过参数表取得流水号,首先一个语法就是取得该参数值并对其所在行加锁,那么
        select xxx in v_xxx from tablename for update;
    就是这个意思。然后你就可以根据你所取得的值进行其他操作,操作全部完成后就可以commit;提交之后,oracle会自动地对您所加锁的对象解锁。-------------
    至于dbms_transaction包,主要是在单独处理存储过程中使用,如果你本身是通过程序调用的,那么只要在你的储存调用过程中使用事务处理即可。
      

  12.   

    谢谢,我已经加了FOR UPDATE,还要看实际在多人操作中有没有再发生类似的情况,呵呵~~
      

  13.   

    不知道你的这个并发量有多大?一般来说一个简单的同行update操作不至于造成无响应的锁定;除非有其它的原因造成了死锁。
      

  14.   

    hehe ,今天变成4个角角了,不过总积分没有变,郁闷