php 自加 性能,对于数据库的自增、自减心得
系統(tǒng)研發(fā)過程中會(huì)有很多地方涉及到自增、自減操作 如:加入版塊時(shí),用戶版塊數(shù)自增1,版塊用戶數(shù)自增1;退出版塊時(shí),用戶版塊數(shù)要減1,版塊用戶數(shù)也要減1
這里推薦:
1.自增可以用
2.自減不要用,而是用重新count結(jié)果的方式。這樣可以確保數(shù)據(jù)的一致性,并且,實(shí)際用戶使用過程中,自減比較少的,大多數(shù)都是自增,重新count一遍,性能并不會(huì)有多少消耗。
$map['uid']=$uid;
$map['fid']=$forum_id;
$res = self::where($map)->find();
//查看版塊關(guān)注表中是否有記錄
self::startTrans();
try{
if ($res) {
if ($res['status'] == 1) { //若有記錄并且已加入,則改為退出狀態(tài),并將該版塊用戶數(shù)減一
$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 { //若有記錄并且已退出版塊,則改為加入,并將該版塊用戶數(shù)加一
$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 { //若沒有記錄則添加加入記錄,并將該版塊用戶數(shù)加一
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); //加入版塊新手任務(wù)
self::commitTrans();
return true;
}catch (\Exception $e){
self::rollbackTrans();
self::setErrorInfo('操作失敗:'.self::getErrorInfo().$e->getMessage());
return false;
}
重點(diǎn):關(guān)于事務(wù)中的update、setField、setInc、setDec的操作,執(zhí)行失敗,也不會(huì)報(bào)exception,事務(wù)不會(huì)回滾
事務(wù)中,對(duì)于數(shù)據(jù)庫(kù)的更新操作,如果where條件查詢不到結(jié)果,更新不會(huì)被執(zhí)行,這樣執(zhí)行結(jié)果為失敗,但不會(huì)拋出異常,事務(wù)繼續(xù)正常向下執(zhí)行。
######面對(duì)如上這種情況,該如何處理呢?有如下2中可選方案
1、保證where條件肯定能查詢到想要的數(shù)據(jù)。比如根據(jù)id查詢,id肯定存在的,不然之前就報(bào)錯(cuò)了。
2、獲取執(zhí)行結(jié)果,如果執(zhí)行結(jié)果$res==0,說明更新操作影響了0行,那么可以調(diào)用exception('更新執(zhí)行失敗');主動(dòng)拋出異常,告訴事務(wù),回滾操作,執(zhí)行失敗。
注意:關(guān)于積分的自減
積分在用戶體系里面尤為特殊且很重要,對(duì)于積分,不適合重新count了,這個(gè)時(shí)候只能用自減。 那么如何保證自減操作不會(huì)出現(xiàn)異常呢?比如,積分制不會(huì)變負(fù)值。 這里有兩步:
1.數(shù)據(jù)庫(kù)字段設(shè)置為unsigned(非負(fù)數(shù))
2.進(jìn)行自減時(shí),where條件里面加上score>=num(score為積分字段,num為要自減的數(shù)值)
如上兩步操作完成后,還有個(gè)問題要注意:涉及到積分變動(dòng),在外圍調(diào)用的時(shí)候都會(huì)用事務(wù)的寫法,這個(gè)時(shí)候,如果加上where條件時(shí),雖然積分自減失敗了,但是數(shù)據(jù)庫(kù)執(zhí)行是正常的,而實(shí)際情況應(yīng)該是執(zhí)行失敗,并回滾所有事務(wù)。那怎么辦呢?
可以考慮檢測(cè)自減操作影響的行數(shù),如果影響行數(shù)為0,說明執(zhí)行失敗,這個(gè)時(shí)候,代碼中可以加上主動(dòng)拋出異常的操作,異常信息為"扣除用戶積分操作失敗!",提醒外圍進(jìn)行回滾事務(wù)。
總結(jié)
以上是生活随笔為你收集整理的php 自加 性能,对于数据库的自增、自减心得的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java怎么把数组怎么放入set,如何将
- 下一篇: php 自动返回,PHP实现自动识别Re