create table zqbwgoodslist (
`sn` int(11) not null auto_increment,
`activeid` int(11) not null comment '活动批次号',
`goodsid` int(11) NOT NULL comment '赠送物品ID',
`num` int(11) not null comment '赠送物品数目',
`firstcondition` int(11) not null default 0 comment '起始条件',
`lastcondition` int(11) not null default 0 comment '结束条件',
`type` tinyint(4) not null comment '活动类别 0-送礼金,1-送装备,2-送道具',
`isactive` tinyint(4) not null default 1 comment '活动是否处于有效期,0-活动关闭,1-活动正在运行中',
`activetype` tinyint(4) not null default 0,
`operater` varchar(64) not null default '' comment '操作人',
primary key(`sn`)
);create table zqbwzengsonglog (
`sn` int not null auto_increment,
`activeid` int(11) NOT NULL DEFAULT '0' comment '活动批次号',
`activetype` int(11) NOT NULL DEFAULT '0' ,
`player_id` int not null comment '玩家ID',
`goods_id` int not null comment '赠送玩家物品编号',
`num` int not null comment '赠送数目',
`type` tinyint not null comment '赠送类型 0-礼卷赠送,1-装备赠送,2-道具赠送,3-资源',
`writetime` datetime not null comment '写入时间',
primary key(`sn`)
);存储过程drop procedure if exists `zqbwtrainingbase`;
delimiter $$
create procedure `zqbwtrainingbase` (
in p_activeid int,
out ResultValue tinyint
)
BEGIN
declare v_goodsid int;
declare v_playerid int;
declare v_level tinyint;
declare v_num int;
declare v_firstcondition,v_lastcondition tinyint;
declare v_type tinyint;
declare done int default 0;
declare cur01 cursor for select `firstcondition`,`lastcondition`,`goodsid`,`num`,`type` from zqbwgoodslist where activeid=p_activeid and isactive=1 and activetype=5;
declare exit handler for not found set done=1;
open cur01;
set Resultvalue=0;
repeat
fetch cur01 into v_firstcondition,v_lastcondition,v_goodsid,v_num,v_type;
if not done then
begin
declare done02 int default 0;
declare cur02 cursor for select player_id,max(level) as level from t_training_base where level>=3 group by player_id;
declare exit handler for not found set done02=1;
open cur02;
repeat
fetch cur02 into v_playerid,v_level;
if not done02 then
if v_level>=v_firstcondition and v_level<=v_lastcondition then
if v_type=0 then
start transaction;
update t_player set gift_certificate=gift_certificate+v_num where player_id=v_playerid;
if @@error_count=0 then
insert into zqbwzengsonglog(`activeid`,`activetype`,`player_id`,`goods_id`,`num`,`type`,`writetime`) values (p_activeid,5,v_playerid,0,v_num,0,now());
commit;
else
set Resultvalue=-2;
rollback;
end if;
elseif v_type=1 then
start transaction;
insert into t_player_equipment(`player_id`,`equipment_id`) values(v_playerid,v_goodsid);
if @@error_count=0 then
insert into zqbwzengsonglog(`activeid`,`activetype`,`player_id`,`goods_id`,`num`,`type`,`writetime`) values (p_activeid,5,v_playerid,v_goodsid,v_num,1,now());
commit;
else
set Resultvalue=-3;
rollback;
end if;
elseif v_type=2 then
start transaction;
insert into t_player_treasure values(v_playerid,v_goodsid,v_num) on duplicate key update num=ifnull(num,0)+v_num;
if @@error_count=0 then
insert into zqbwzengsonglog(`activeid`,`activetype`,`player_id`,`goods_id`,`num`,`type`,`writetime`) values (`p_activeid`,5,v_playerid,v_goodsid,v_num,2,now());
commit; else
set Resultvalue=-4;
rollback;
end if;
else
set Resultvalue=-5;
set done02=1;
end if;
end if;
end if;
until done02=1 end repeat;
end;
end if;
until done=1 end repeat;
close cur01;
END $$
delimiter ;现在碰到的问题是,在对一大批玩家进行道具赠送的时候会有极少数的玩家收不到物品(即对应的t_player_treasure表没有插入该玩家的数据),但是我们查看日志又发现在zqbwzengsonglog这张日志表里又能找到该玩家的赠送记录,也就是说,在同一个事务里insert into t_player_treasure表没有成功,而insert into zqbwzengsonglog却成功了,纠结中,忘大侠们帮找找这个过程的BUG。
`sn` int(11) not null auto_increment,
`activeid` int(11) not null comment '活动批次号',
`goodsid` int(11) NOT NULL comment '赠送物品ID',
`num` int(11) not null comment '赠送物品数目',
`firstcondition` int(11) not null default 0 comment '起始条件',
`lastcondition` int(11) not null default 0 comment '结束条件',
`type` tinyint(4) not null comment '活动类别 0-送礼金,1-送装备,2-送道具',
`isactive` tinyint(4) not null default 1 comment '活动是否处于有效期,0-活动关闭,1-活动正在运行中',
`activetype` tinyint(4) not null default 0,
`operater` varchar(64) not null default '' comment '操作人',
primary key(`sn`)
);create table zqbwzengsonglog (
`sn` int not null auto_increment,
`activeid` int(11) NOT NULL DEFAULT '0' comment '活动批次号',
`activetype` int(11) NOT NULL DEFAULT '0' ,
`player_id` int not null comment '玩家ID',
`goods_id` int not null comment '赠送玩家物品编号',
`num` int not null comment '赠送数目',
`type` tinyint not null comment '赠送类型 0-礼卷赠送,1-装备赠送,2-道具赠送,3-资源',
`writetime` datetime not null comment '写入时间',
primary key(`sn`)
);存储过程drop procedure if exists `zqbwtrainingbase`;
delimiter $$
create procedure `zqbwtrainingbase` (
in p_activeid int,
out ResultValue tinyint
)
BEGIN
declare v_goodsid int;
declare v_playerid int;
declare v_level tinyint;
declare v_num int;
declare v_firstcondition,v_lastcondition tinyint;
declare v_type tinyint;
declare done int default 0;
declare cur01 cursor for select `firstcondition`,`lastcondition`,`goodsid`,`num`,`type` from zqbwgoodslist where activeid=p_activeid and isactive=1 and activetype=5;
declare exit handler for not found set done=1;
open cur01;
set Resultvalue=0;
repeat
fetch cur01 into v_firstcondition,v_lastcondition,v_goodsid,v_num,v_type;
if not done then
begin
declare done02 int default 0;
declare cur02 cursor for select player_id,max(level) as level from t_training_base where level>=3 group by player_id;
declare exit handler for not found set done02=1;
open cur02;
repeat
fetch cur02 into v_playerid,v_level;
if not done02 then
if v_level>=v_firstcondition and v_level<=v_lastcondition then
if v_type=0 then
start transaction;
update t_player set gift_certificate=gift_certificate+v_num where player_id=v_playerid;
if @@error_count=0 then
insert into zqbwzengsonglog(`activeid`,`activetype`,`player_id`,`goods_id`,`num`,`type`,`writetime`) values (p_activeid,5,v_playerid,0,v_num,0,now());
commit;
else
set Resultvalue=-2;
rollback;
end if;
elseif v_type=1 then
start transaction;
insert into t_player_equipment(`player_id`,`equipment_id`) values(v_playerid,v_goodsid);
if @@error_count=0 then
insert into zqbwzengsonglog(`activeid`,`activetype`,`player_id`,`goods_id`,`num`,`type`,`writetime`) values (p_activeid,5,v_playerid,v_goodsid,v_num,1,now());
commit;
else
set Resultvalue=-3;
rollback;
end if;
elseif v_type=2 then
start transaction;
insert into t_player_treasure values(v_playerid,v_goodsid,v_num) on duplicate key update num=ifnull(num,0)+v_num;
if @@error_count=0 then
insert into zqbwzengsonglog(`activeid`,`activetype`,`player_id`,`goods_id`,`num`,`type`,`writetime`) values (`p_activeid`,5,v_playerid,v_goodsid,v_num,2,now());
commit; else
set Resultvalue=-4;
rollback;
end if;
else
set Resultvalue=-5;
set done02=1;
end if;
end if;
end if;
until done02=1 end repeat;
end;
end if;
until done=1 end repeat;
close cur01;
END $$
delimiter ;现在碰到的问题是,在对一大批玩家进行道具赠送的时候会有极少数的玩家收不到物品(即对应的t_player_treasure表没有插入该玩家的数据),但是我们查看日志又发现在zqbwzengsonglog这张日志表里又能找到该玩家的赠送记录,也就是说,在同一个事务里insert into t_player_treasure表没有成功,而insert into zqbwzengsonglog却成功了,纠结中,忘大侠们帮找找这个过程的BUG。
show create table zqbwzengsonglog ;
贴出来看一下 ,你的表是什么存储引擎? MYISAM不支持事务。
在第二个begin后 加个语句。
DECLARE exit HANDLER FOR SQLEXCEPTION rollback;