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,说明执行失败,这个时候,代码中可以加上主动抛出异常的操作,异常信息为"扣除用户积分操作失败!",提醒外围进行回滚事务。
php 自加 性能,对于数据库的自增、自减心得相关推荐
- 使用redis缓存加索引处理数据库百万级并发
使用redis缓存加索引处理数据库百万级并发 前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1 ...
- Geospark加载PostgreSQL数据库
title: (七)GeoSpark与PostgreSQL date: 2021-05-12 16:38:23 tags: GeoSpark PostGreSQL以及Mysql均有空间引擎扩展,且Ge ...
- oracle定时加载文件,采用sqlldr定时将文本文件加载进入数据库
需求:每个小时前台生成一个追踪文件,文件名格式为yyyymmddhh,存放在linux服务器上,要求每小时将上一个小时生成的文件导入数据库 解决方案: 采用sqlldr可以快速的将外部文本文件加载到数 ...
- AE中加载个人数据库GDB方法探讨
AE中加载个人数据库GDB方法探讨 下面对AE中加载个人数据库的方法做一个总结: 个人数据库是保存在Access中的数据库.其加载方式有两种:通过名字和通过属性加载(也许不只这两种,AE中实现同一功能 ...
- mysql重装系统后以前的数据_系统重装后,Mysql数据库重装加载原来数据库
mysql 5.6 后热数据的加载 mysql 5.6 后热数据的加载 转自:http://blog.itpub.net/20892230/viewspace-2127469/ 故障现象:在数据库重启 ...
- java调用oracle删除,使用IDEA对Oracle数据库进行简单增删改查操作
1.1 java中的数据存储技术 在java中,数据库存取技术可分为如下几类: 1.jdbc直接访问数据库 2.jdo(java data object)是java对象持久化的新的规范,也是一个用于存 ...
- jaba窗体连接mysql增删改查_知识实现——Java使用jdbc连接MySql数据库,实现增删改查...
Java使用jdbc连接MySql数据库,实现增删改查 首先,导入MySql连接数据库的jar包,我用的是 mysql连接jar包 DB类,用于获得数据库连接 import java.sql.Driv ...
- mysql linux导入csv主键,MySQL导入csv文件内容到Table及数据库的自增主键设置
写在前面 目的是测试将csv文件内容导入到表中, 同时记录一下自增主键的设置. 测试采用MySQL8.0. 新建表customer_info如下, 未设置主键. 修改上表, 添加主键id, 并设置为自 ...
- mysql创建数据表列子,MySQL 创建数据库及简单增删改查
MySQL 创建数据库及简单增删改查 我们可以在登陆 MySQL 服务后,使用 create 命令创建数据库,语法如下: CREATE DATABASE 数据库名; 登入: Enter passwor ...
最新文章
- 机器学习中,有哪些特征选择的工程方法?
- 理解MapReduce
- mysql user 用户名长度_为什么注册的用户账号长度不能超过5个字符
- c语言malloc函数用法_小白对c语言数组的基础总结
- 如何跟踪log4j漏洞原理及发现绕WAF的tips
- 让IE6-IE8 支持HTML5
- 《软件工程实践》第三次作业-原型设计(结对第一次)
- Kali Linux 网络扫描秘籍 第二章 探索扫描(二)
- linux6.3 插u盘,U盘安装centos 6.3教程(超级详细教程)
- 艰苦的编译boost python (失败)
- 用python做一个搜索引擎(Pylucene)
- linux系统苹果刷机,iPhone上安装Android系统详细步骤
- lpx寒假作业案例8
- unity 是厘米还是米_cm是厘米还是毫米
- 华为鸿蒙到底卡不卡,华为mate book14,办公作图就靠它了
- 解决在MATLAB Simulink Library Browser找不到Car Sim S-Function的问题
- 85D - Sum of Medians
- 表单form中的submit事件
- MapReduce的核心资料索引 [转]
- 有苦有乐的算法 --- 小和问题
热门文章
- 小程序判断用户在线状态
- iOS8.0 之后指纹解锁
- 聊聊spring cloud gateway的PreserveHostHeaderGatewayFilter
- 人的原罪、本我和超我
- 《Python和Pygame游戏开发指南》——2.16 pygame.display.update()函数
- AngularJs表单自动验证
- 测试驱动开发与行为驱动开发中的测试先行方法
- Posted content type isn't multipart/form-data
- jhello框架-ajax
- 附录G Netty与NettyUtils