0

我正在尝试缓存聚合,但由于并发性可能会遇到参照完整性违规..

这是我正在做的事情(有点归结):

select  low, high
into    l_low, l_high
from    nasd_stats
where   symbol_id = l_symbol_id;

if( l_low is NULL ) then 
      select  max(last),
              min(last)  
      into    l_high, l_low
      from    nasd
      where   symbol_id = l_symbol_id;

      insert  into nasd_stats values ( l_symbol_id, l_low, l_high );
end if;

因此,两个用户可以运行具有此代码的存储过程,并同时检测到 l_low 为空,然后在 min/max 聚合之后同时尝试并插入到 nasd_stats 中(其中一个将失败,因为 nasd_stats 上有一个基于 symbol_id 的唯一键)。

知道如何防止这种情况发生吗?

我猜我可以这样做:

Start Transaction;
delete from nasd_stats where symbol_id = l_symbol_id;
insert into nasd_stats values ( l_symbol_id, l_low, l_high;
Commit;

逻辑是,删除会锁定行(即使它不存在),然后插入会做我想做的事。

TIA。

大学教师

4

2 回答 2

1

如果键是在 symbol_id 字段上定义的,则按以下方式执行查询

insert  into nasd_stats Select  distinct l_symbol_id, l_low, l_high  from nasd_stats where not exists (Select 1 from nasd_stats where symbol_id  = l_symbol_id) ;
于 2012-04-29T10:37:49.980 回答
0

您可以只检查插入中的符号 ID 并且它存在然后有人已经得到它,所以您不需要再插入?

所以你的代码是一样的,但是插入语句是

  insert  into nasd_stats values ( l_symbol_id, l_low, l_high ) where symbol_id =    l_symbol_id AND l_low is NULL ;
于 2013-09-24T20:38:06.527 回答