« 分配IP地址--朝阳提出的问题 | Main | Happy Children's Day! »

分配IP地址--朝阳提出的问题(2)

按照昨天讨论的方法,我写了一个简单的存储过程模拟申请IP的过程,并请朝阳看看,有没有什么问题。

我的大概步骤是这样的:

create table test_ip_table(id number(9) primary key, ip_addr varchar2(20), used varchar2(3));create table test_ip_table_log(seq number, id  number, sleep_time number, apply varchar2(6), now_used number, release number); create sequence SEQ_test_ip_tableminvalue 1maxvalue 999999999999999start with 1increment by 1cache 10;

insert into test_ip_tableselect rownum,'192.168.0.'||rownum,'N'from dba_tables awhere rownum<=5;commit;

用于申请IP的过程:

create or replace procedure proc_test_ip_table(num in number) is  n_seq number(9);  n_id  number(9);  v_state varchar2(3);  v_state2 varchar2(3);  v_result varchar2(6);  n_sleep number(9,3);     --  v_cnt  number;  n_release_id number;  n_rn number;  --  v_msg varchar2(2000); begin    --PART 1  申请IP  begin    select SEQ_test_ip_table.Nextval into n_seq from dual;     select mod(n_seq,num) into n_id from dual;    select used into v_state from test_ip_table where id = n_id;        if(v_state='N')    then      --随机休眠一段时间,模拟未及时提交      select trunc(dbms_random.value(0,20),2) into n_sleep from dual;      dbms_lock.sleep(n_sleep);            --置已用标志      --再次判断改IP是否被人使用      select used into v_state2 from test_ip_table where id = n_id;      if v_state='N'      then         update test_ip_table set used='Y' where id=n_id;        v_result:='SUCC';--成功申请        commit;      else          v_result:='FAIL';--未成功提交      end if;    else      v_result:='CANNOT';--IP不可用    end if;            select count(*) into v_cnt from test_ip_table where used='Y';        insert into test_ip_table_log(seq,id,sleep_time,apply,now_used)    values(n_seq,n_id,n_sleep,v_result,v_cnt);    commit;        --PART 2 随机释放一个目前在用的IP    if (sign(dbms_random.value(-1,1))>=0)    then      select count(*) into v_cnt from test_ip_table where used='Y';      if v_cnt>0 then        select trunc(dbms_random.value(1,v_cnt)) into n_rn from dual;                if n_rn >0        then          select id into n_release_id          from (select rownum rn,id from test_ip_table where used='Y')          where rn=n_rn;          end if;                update test_ip_table set used='N' where id=n_release_id;        update test_ip_table_log        set release=n_release_id        where seq=n_seq;      end if;      commit;          end if;    exception when others then       rollback;    v_msg:=sqlerrm;     end;  end proc_test_ip_table;

然后测试时,开10个session同时执行proc_test_ip_table(5);分别若干次。

纪录的log如下:SQL> select * from test_ip_table_log;       SEQ         ID SLEEP_TIME APPLY    NOW_USED    RELEASE---------- ---------- ---------- ------ ---------- ----------       491          1       0.95 SUCC            1        496          1            CANNOT          1          1       494          4       2.54 SUCC            1        497          2      16.16 SUCC            2        499          4            CANNOT          2        493          3      20.96 SUCC            3          3       502          2            CANNOT          2        498          3      18.41 SUCC            3        504          4            CANNOT          3  

原来考虑可能会出现的v_result:='FAIL';–未成功提交 并没有出现Embarassed


作者: sopher | 可以转载, 转载时务必以超链接形式标明文章原始出处和作者信息及版权声明

网址: http://www.color-cc.com/2006/05/ip2.html

Posted on May 31, 2006 12:05 PM Under Database. Tags :. RSS-Feed. TrackBack URL for this entry:
http://www.color-cc.com/mt/mt-tb.cgi/282.

Post a comment