php 自加 性能,对于数据库的自增、自减心得

系统研发过程中会有很多地方涉及到自增、自减操作 如:加入版块时,用户版块数自增1,版块用户数自增1;退出版块时,用户版块数要减1,版块用户数也要减1

这里推荐:

1.自增可以用

2.自减不要用,而是用重新count结果的方式。这样可以确保数据的一致性,并且,实际用户使用过程中,自减比较少的,大多数都是自增,重新count一遍,性能并不会有多少消耗。

$map['uid']=$uid;

$map['fid']=$forum_id;

$res = self::where($map)->find();

//查看版块关注表中是否有记录

self::startTrans();

try{

if ($res) {

if ($res['status'] == 1) { //若有记录并且已加入,则改为退出状态,并将该版块用户数减一

$status = 0;

$now_count=self::where('fid',$forum_id)->where('status',1)->count();

ComForum::where('id', $forum_id)->setField('member_count',$now_count-1);

$forum_count=self::getForumCount($uid);

UserModel::where('uid',$uid)->setField('forum_count',$forum_count-1);

//退出版块日志

action_log($uid,2,'退出版块');

} else { //若有记录并且已退出版块,则改为加入,并将该版块用户数加一

$status = 1;

ComForum::where('id', $forum_id)->setInc('member_count');

UserModel::where('uid',$uid)->setInc('forum_count');

//加入版块日志

action_log($uid,1,'加入版块');

}

self::update(['status'=>$status],$map); //更新操作

} else { //若没有记录则添加加入记录,并将该版块用户数加一

self::add(['uid' => $uid, 'fid' => $forum_id,'status'=>1,'create_time'=>time()]);

ComForum::where('id', $forum_id)->setInc('member_count');

UserModel::where('uid',$uid)->setInc('forum_count');

//加入版块日志

action_log($uid,1,'加入版块');

}

UserTaskNew::newAddToForum($uid); //加入版块新手任务

self::commitTrans();

return true;

}catch (\Exception $e){

self::rollbackTrans();

self::setErrorInfo('操作失败:'.self::getErrorInfo().$e->getMessage());

return false;

}

重点:关于事务中的update、setField、setInc、setDec的操作,执行失败,也不会报exception,事务不会回滚

事务中,对于数据库的更新操作,如果where条件查询不到结果,更新不会被执行,这样执行结果为失败,但不会抛出异常,事务继续正常向下执行。

######面对如上这种情况,该如何处理呢?有如下2中可选方案

1、保证where条件肯定能查询到想要的数据。比如根据id查询,id肯定存在的,不然之前就报错了。

2、获取执行结果,如果执行结果$res==0,说明更新操作影响了0行,那么可以调用exception('更新执行失败');主动抛出异常,告诉事务,回滚操作,执行失败。

注意:关于积分的自减

积分在用户体系里面尤为特殊且很重要,对于积分,不适合重新count了,这个时候只能用自减。 那么如何保证自减操作不会出现异常呢?比如,积分制不会变负值。 这里有两步:

1.数据库字段设置为unsigned(非负数)

2.进行自减时,where条件里面加上score>=num(score为积分字段,num为要自减的数值)

如上两步操作完成后,还有个问题要注意:涉及到积分变动,在外围调用的时候都会用事务的写法,这个时候,如果加上where条件时,虽然积分自减失败了,但是数据库执行是正常的,而实际情况应该是执行失败,并回滚所有事务。那怎么办呢?

可以考虑检测自减操作影响的行数,如果影响行数为0,说明执行失败,这个时候,代码中可以加上主动抛出异常的操作,异常信息为"扣除用户积分操作失败!",提醒外围进行回滚事务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值