精华帖 (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语句来插入记录,记录中的lastid为2(这时,表未锁)。 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了也利与多种数据库
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-03-06
这是真实项目中的应用吗?
|
|
返回顶楼 | |
发表时间:2009-03-06
不是很懂!
|
|
返回顶楼 | |
发表时间:2009-03-06
charles751 写道 这是真实项目中的应用吗?
是的 |
|
返回顶楼 | |
发表时间: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; / |
|
返回顶楼 | |
浏览 7107 次