有一个oracle数据表,每次增加一条记录都是使用sequence号作为关键字。假设有很多人同时对该表增加记录,增加后还要获取到增加的sequence号是多少。那么就有可能出现一个人增加后,还未取回该号之前,另一个又增加一条记录。这时再取回主键号就不是他增加的那个号的问题。
但如果在他增加之前就锁定该表,在取回主键后再释放该表的话,就可以解决这个问题。请问,java是如何实现这个功能的?
下面是我设想的伪代码:
  
  if (lockTable())
  {
   insertTable();
   getPrimaryNum();
  }
  else
  {
    Log("该表被锁定!");
  }
  releaseTable();
  这里的lockTable和releaseTable该如何实现?
  

解决方案 »

  1.   

    是否可以在方法里加锁,同一时间只允许一个线程调用插入表方法
    synchronized void insertTable(){}
      

  2.   

    SELECT…FOR UPDATE 就可以
    Oracle锁表
    行级锁
    表级锁
    行级锁
             ---- 行被排他锁定
             ----在某行的锁被释放之前,其他用户不能修改此行
             ----使用 commit 或 rollback 命令释放锁
             ----Oracle 通过使用 INSERT、UPDATE 和 SELECT…FOR UPDATE 语句自动获取行级锁
    SELECT…FOR UPDATE 子句
    ―在表的一行或多行上放置排他锁
    ―用于防止其他用户更新该行
    ―可以执行除更新之外的其他操作
    ―select * from goods where gid=1001
    ―for update of gname;
    ―只有该用户提交事务,其他用户才能够更新gnameFOR UPDATE WAIT 子句 
    ―Oracle9i 中的新增功能 
    ―防止无限期地等待锁定的行 
    ―等待间隔必须指定为数值文字 
    ―等待间隔不能是表达式、赋值变量或 PL/SQL
    变量 
    ―select * from goods where gid=1001 for update of gname wait        3 
    ―等待用户释放更新锁的时间为3秒,否则超时。
    •表级锁
    ―保护表的数据
    ―在多个用户同时访问数据时确保数据的完整性
    ―可以设置为三种模式:共享、共享更新和 排他
              语法:lock table<table_name>in<mode>;
    共享锁
    ―锁定表
    ―仅允许其他用户执行查询操作
    ―不能插入、更新和删除
    ―多个用户可以同时在同一表中放置此锁
    ―lock table table_name
    ―in share mode [nowait];
    ― rollback 和commit 命令释放锁
    ― nowait 关键字告诉其他用户不用等待
    共享更新锁
    ―锁定要被更新的行
    ―允许其他用户同时查询、插入、更新未被锁定的行
    ―在 SELECT 语句中使用“FOR UPDATE”子句,可以强制使用共享更新锁
    ―允许多个用户同时锁定表的不同行
    加锁的两种方法
                lock table tab_name in share update mode;
                select column1,column2
                from goods
                where goods
                where gid=1001
                for update of column1,column2
    排他锁
    ―与其他两种锁相比,排他锁是限制性最强的表锁
    ―仅允许其他用户查询数据
    ―不允许执行插入、删除和更新操作
    ―在同一时间仅允许一位用户在表上放置排他锁
    ―共享锁与此相反         lock table tab_name in exclusive mode;
             lock table<表名>[<表名>]...
                       in share mode [nowait]
       
             lock table< 表名>[<表名>]...
             in exclusive mode [nowait]
             lock table<表名>[<表名>]...
             in share update mode[nowait]
      

  3.   

    执行sql,写sql的时候写成FOR UPDATE WAIT之类的,根据需求看ls的
      

  4.   

    kingssman
    我要知道的是java的用法,能把java和sql综合一下讲解一下吗?
      

  5.   

    ouyangxiaokang6
    根据需求看ls的
    呵呵,ls什么意思啊?
      

  6.   

    09江城地产丽人秀参赛选手 泰驰伊顿阳光:张慧
    http://news.wuhan.soufun.com/2009-03-19/2464851.htm
    她的博客地址:
    http://blog.soufun.com/blog_23226825.htm
    请大家务必多多支持,谢谢各位兄弟姐妹!
    张龙在这里真心的谢谢大家!
    http://newhouse.wuhan.soufun.com/zt/200903/09jclrx.html
    点我的相片为我刷刷人气。点点博客也可以刷人气
      

  7.   

    刚好我也需要这个答案!www.sgjiajiao.com
      

  8.   

    java主要就是依靠线程同步来实现的。或者就是你用数据库里面的更新时间来实现,
    比如
    每次操作表都把更新时间保存下来,
    下次插入的时候去和这个时间比较,
    如果不一致就说明别的人在暂用。
      

  9.   

    我能否使用kingssman给出的提示?使用排他锁。
     
      if (lockTable())          //lock table tab_name in exclusive mode; 
      { 
      insertTable(); 
      getPrimaryNum(); 
      } 
      else 
      { 
        Log("该表被锁定!"); 
      } 
      releaseTable();         //在这里commit,释放锁。当然,使用zabaglione的方法,获取插入记录的时间也是存在问题的,如果访问量很大的情况下,在同一秒上同时插入了多条,怎么去判断呢?获取插入时间还是有些问题的吧。?
      

  10.   

    一般我遇到这种问题,我都是先从数据库中通过SQL语句将sequence号取出来
    SQL语句:select sequence_name from dual然后在插入到表中
      

  11.   

    用java检索sequence,取得sequence值,保存到java程序中然后再进行插入如果用sequence管理的话,没必要进行锁表吧?