我正在尝试缓存聚合,但由于并发可能会遇到参照完整性违规..
这就是我正在做的事情(有点夸张):
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;
因此,两个用户可以运行具有此代码的sproc,同时检测l_low为null,然后在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。
唐
答案 0 :(得分: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) ;
答案 1 :(得分:0)
您是否可以检查插入中的符号ID,它是否存在然后有人已经到达它,所以您不需要再插入一次?
所以你的代码是相同的,但是insert语句是
insert into nasd_stats values ( l_symbol_id, l_low, l_high ) where symbol_id = l_symbol_id AND l_low is NULL ;