现在有一个用户参与活动的表,字段包含用户号码,是否中奖两个字段。select count(1) into v_temp_count from table where gift =1;
if v_temp_count > 1 then--当一等奖已被抽掉,用户不能再中一等奖
insert into table(phone_number,gift)values(phone,0);--插入用户未中奖记录
end if;
因为服务器是集群的,所以需要在数据库端进行锁操作。但是oracle中查询是不能锁的。
那么如何保证查询count和insert在同一原子操作中呢?!
if v_temp_count > 1 then--当一等奖已被抽掉,用户不能再中一等奖
insert into table(phone_number,gift)values(phone,0);--插入用户未中奖记录
end if;
因为服务器是集群的,所以需要在数据库端进行锁操作。但是oracle中查询是不能锁的。
那么如何保证查询count和insert在同一原子操作中呢?!
--如果中奖,修改中奖记录表
if v_gift = 1 then
select t.one into v_temp_count from t_rbt_gift9_result t for update;
if v_temp_count < v_gift_one then
update t_rbt_gift9_result t set t.one = (t.one + 1) where t.id = 1;
else
v_gift := 0;
end if;
insert into t_rbt_gift9_info (ID,phone_number,gift,create_time,random_num)
values(seq_rbt_gift9_info.nextval,v_phone_number,v_gift,sysdate,v_random);
elsif v_gift = 2 then
select t.two into v_temp_count from t_rbt_gift9_result t for update;
if v_temp_count < v_gift_two then
update t_rbt_gift9_result t set t.two = (t.two + 1) where t.id = 1;
else
v_gift := 0;
end if;
insert into t_rbt_gift9_info (ID,phone_number,gift,create_time,random_num)
values(seq_rbt_gift9_info.nextval,v_phone_number,v_gift,sysdate,v_random);
elsif v_gift = 3 then
select t.three into v_temp_count from t_rbt_gift9_result t for update;
if v_temp_count < v_gift_three then
update t_rbt_gift9_result t set t.three = (t.three + 1) where t.id = 1;
else
v_gift := 0;
end if;
insert into t_rbt_gift9_info (ID,phone_number,gift,create_time,random_num)
values(seq_rbt_gift9_info.nextval,v_phone_number,v_gift,sysdate,v_random);
else--插入未中奖信息
insert into t_rbt_gift9_info (ID,phone_number,gift,create_time,random_num)
values(seq_rbt_gift9_info.nextval,v_phone_number,v_gift,sysdate,v_random);
end if;现在的处理方式是这样。
是这样的,原来只有一个表的情况下,如果两个线程通过count查询当前中奖数都是0,当第一个线程执入中奖信息的时候,第二个线程还会再插入中奖信息,因为count不会锁表。两个线程查询出来都是没有超出中奖上限的。所以都会插入表。
你是不是说begin end中,一次只能有一个线程访问吗?