论坛首页 Java企业应用论坛

利用oracle的存储过程实现在sys_sequence表中的多个的自动增长ID的多线程同步解决方案

浏览 7107 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-05   最后修改:2009-03-06

利用oracle的存储过程实现sys_sequence表的自动增长ID的多线程同步解决方案

 

sys_sequence表结构

sys_sequence表中的记录

 

 

DECLARE

               no NUMBER(10);

               key VARCHAR(50);

            begin

             key := ?;

             begin select lastid into no  from sys_sequence where code = key for update;

                   // 首先从sys_sequence找到相应表的lastid值,并使用for update后缀来锁住该记录。

             exception when no_data_found then no := 1;

                   // 截获no_data_found错误,当sys_sequence表中无记录时,lastid默认为1

             end;            

             if no>1 then

                update sys_sequence set lastid=no+1 where code=key;

                  // lastid大于1即表中存在记录时,使用update语句来更新该记录。

             else

                begin

                insert into sys_sequence (code,lastid) values(key,2);

                   // lastid==1时,即表中不存在记录,使用insert语句来插入记录,记录中的lastid2(这时,表未锁)。

                exception when DUP_VAL_ON_INDEX then

                  // 所以当有另外一个线程同步访问该表,并插入了code值相同的记录,oracle就会抛出DUP_VAL_ON_INDEX异常,意味着表中已经记录,不能使用insert语句。

                   select lastid into no  from sys_sequence where code = key for update;

                  // 重新查询表,获取lastid,并使用for update来锁记录

                   update sys_sequence set lastid=no+1 where code=key;

                  // 放心使用update语句来更新记录,这时已获得记录锁,无需担心同步问题。

                end;

             end if;

            ?:=no;

            end;;

 

可以少见几个oracle的sequence了也利与多种数据库

 

  • 大小: 36.5 KB
  • 大小: 98.1 KB
   发表时间:2009-03-06  
这是真实项目中的应用吗?

0 请登录后投票
   发表时间:2009-03-06  
不是很懂!
0 请登录后投票
   发表时间:2009-03-06  
charles751 写道
这是真实项目中的应用吗?


是的
0 请登录后投票
   发表时间:2009-03-07   最后修改:2009-03-07
其实这个完全可以再简化一些:

create or replace procedure get_sequence(key in varchar2) return number
  ret_val sys_sequence.lastid%type;
begin
  update sys_sequence
     set lastid = lastid + 1
   where code = key;

  if sql%notfound then
    insert into sys_sequence(code, lastid)
    values (key, 1);
  end if;

  select lastid
    into ret_val
   where code = key;

  return ret_val;
end;
/

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics