一个无限刷道具的非典型bug

03/26/2025    gamedev golang

临下班的时候遇到个锅,分享下

一个每天刷新的业务,数据库对象加了个新属性是个 map ,服务器更新的时间已经远远过了刷新时间,也就是说很多玩家当天的数据结构已经固定了,此时新代码上去,新加的 map 从数据库读出来是 nil ,读操作就空指针

业务涉及到了给道具,顺序是这样的:

  1. 读玩家数据
  2. 根据玩家数据做各种业务判断
  3. 业务判断通过给道具
  4. 更新玩家数据状态
  5. 更新数据库

在第3步空指针爆炸了,但给道具在前面,所以给道具成功了

又更新数据库这步因为报错走不到,状态没有写进数据库

玩家一直请求,就能一直获取道具

好在这个道具价值不高而且上限很低,到了上限就加不上去了,这就是个无限刷道具的bug

教训:

  • 已存在的业务,对数据对象新加属性时,后面用到新加属性一定要判断是否为nil

  • 所有加道具的业务,都应该先读写数据成功,才给道具

顺序应该修改成:

  1. 读玩家数据
  2. 根据玩家数据做各种业务判断
  3. 业务判断通过更新玩家数据状态
  4. 更新数据库
  5. 给道具

PS. 抛开事实不谈,golang 难道一点锅没有吗?如果是 java ,在加属性时直接跟一个 new 做初始化,就算数据库没有这个属性,也不至于会空指针