MYSQL 高并发下,记录变动后余额怎么统计才能更准确?

2023-12-05 10:51:12 +08:00
 Aluhao
-- 积分总表
CREATE TABLE `api_credits` (
`uid` bigint unsigned NOT NULL COMMENT '用户 ID',
`names` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户姓名',
`credits1` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '积分 1 余额',
`credits2` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '积分 2 余额',
`credits3` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '积分 3 余额',
`time` int NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB COMMENT='积分总表';

-- 积分记录表
CREATE TABLE `api_credits_log` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '记录 ID',
`uid` bigint unsigned NOT NULL DEFAULT '0' COMMENT '用户 ID',
`credits` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '积分变动',
`balance` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '变动后余额',
`cid` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '操作类型',
`time` int unsigned NOT NULL DEFAULT '0' COMMENT '记录时间',
PRIMARY KEY (`id`),
KEY `uid_time` (`uid`,`time`)
) ENGINE=InnoDB COMMENT='积分记录表';

消费 100 积分,向 积分总表 api_credits 减去用户总积分,并向积分记录表 api_credits_log 写入一条记录,
balance 用户余额计算是 api_credits 表中 credits1 - 100 (即 80000 - 100 = 79900 )

消费事务会产生 SQL 数据:
SELECT * FROM `api_credits` WHERE `uid`='22' LIMIT 1
UPDATE `api_credits` SET `credits1`=`credits1`-'100' WHERE `uid`='22' AND `credits1`>='100'
INSERT INTO `api_credits_log` SET `uid`='22', `cid`='3', `credits`='100', `balance`='79900', `time`='1701001020'

但是在高并发场景下 SELECT 读出来的值不是最新,如,在同一时间段这个用户同时几条消费记录,这个变动后余额统计的就不是这么准确了,有没有什么好点的解决方案?

系统用了主从架构,读写分离,但是在这条事务中 SELECT 查的是主库

欢迎大家一起探讨一下。
6629 次点击
所在节点    MySQL
63 条回复
kanepan19
2023-12-06 12:04:51 +08:00
@TUNGH
是这样的, 就是性能和 一致性的取舍问题。
pincoudeduanyin
241 天前
@allenzhangSB 老哥,🐂,这个方案很好,我也碰到这种问题了,但是我想问下,这样子 update ,应该和正常的 update ,性能上是没有区别的吧
allenzhangSB
241 天前
@pincoudeduanyin 性能上没区别, 要注意下这个变量的生命周期等, 具体可以再查下资料有哪些注意事项, 我也是很多年前用过, 有些细节忘记了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/997702

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX