利用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了也利与多种数据库