CREATE OR REPLACE PROCEDURE Campaignprize_range( CampaignIdd NUMBER,PrizeTypeIdd NUMBER,ServerIndex VARCHAR2, RETVAL OUT VARCHAR2) IS hashcoded VARCHAR2(8); prizetypenum number(6); prizetypenumold number(6); prizetypenumc VARCHAR2(6); datacount number(6); totalcount number(6); flag number(1); single number(6); BEGIN flag:=0; RETVAL :=''; single:=0; SELECT count(1) into totalcount FROM mkt_campaignprize a WHERE a.campaignid=CampaignIdd AND a.issend=0 and a.prizetypeid=PrizeTypeIdd and a.hashcode like ''||ServerIndex||'%' order by a.campaignprizeid asc; DECLARE CURSOR c1 IS SELECT a.hashcode,a.campaignprizeid FROM mkt_campaignprize a WHERE a.campaignid=CampaignIdd AND a.issend=0 and a.prizetypeid=PrizeTypeIdd and a.hashcode like ''||ServerIndex||'%' order by a.campaignprizeid asc; BEGIN FOR r1 IN c1 LOOP prizetypenumold:= to_number( substr(r1.hashcode,3,6)); single:=single+1; if flag=0 then RETVAL :=RETVAL||prizetypenumold; if totalcount=single then RETVAL :=RETVAL||','||prizetypenumold||'$'; end if; flag:=1; if totalcount=1 then RETVAL :=RETVAL||','||prizetypenumold||'$'; end if; else prizetypenum:=prizetypenumold+1; prizetypenumc:=lpad(prizetypenum,6,'0'); hashcoded:=ServerIndex||prizetypenumc; select count(1) into datacount from mkt_campaignprize a WHERE a.campaignid=CampaignIdd AND a.issend=0 and a.prizetypeid=PrizeTypeIdd and a.hashcode=hashcoded; if datacount<1 or single=totalcount then RETVAL :=RETVAL||','||prizetypenumold||'$'; flag:=0; end if; end if; END LOOP; END; Exception When others then RETVAL :='E'||SUBSTR(SQLERRM, 1, 600); END Campaignprize_range;
简要介绍下场景:传入的参数CampaignIdd 为活动ID,PrizeTypeIdd为奖品ID,ServerIndex为服务器编号,这里的表mkt_campaignprize是一个给活动配置的奖品表,而这里此存储过程的目的是查询hashcode 字段,该自动在插入的时候就做了处理 :是根据CampaignId,PrizeTypeId,ServerIndex查询出来的值递增顺序存储的,但是也有个别情况,比如删除等操作,使这里的hashcode值有空缺,使这里的值变成了多个区间,而上面的存储过程就是利用游标的形式取的各个区间起始末尾值,而取此区间的值得目的就是系统将此区间值存入缓存中,这样在大数据量礼品的时候可以只存各区间的起始末尾值就可以,系统在实际发奖的时候并不需要都来数据库该表中查询可用的奖品,因为这样在高并发的时候回导致资源的冲突,事务提交的对等问题,产生这样的问题就是因为用户在查询到可用的奖品后拿走后还要去改对应拿走奖品记录的状态,如果同时多人查询出同一个奖品都去更新一条记录的时候就出现冲突,而现在的方式,将奖品的取值的区间存入系统全局缓存,利用线程同步锁的方式,让用户再高并发访问的时候排队在缓存中取对应奖品的记录的hashcode,同时移除到以拿到的奖品,后者来到就不会再拿到,因为缓存是内存,而且只是在其中执行了简单的拿区间值得算法因此访问速度快,大家排队时间极短,大家分别拿到自己制定数据奖品的hashcode后再去数据库查对应的记录 更新对应的记录就不会有资源冲突。