如何管理锁以防止重复插入

时间:2012-04-29 10:06:13

标签: mysql

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

这就是我正在做的事情(有点夸张):

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。

2 个答案:

答案 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 ;