如果代码中的字段与数据库中的字段类型不一致会导致什么结果?那么很有可能出现用户“空手套白狼”的情况出现!
我跟我做游戏开发时的研发总监叙旧的时候,聊起了之前我们系统里面出现的一个Bug,这个Bug真的是令人印象深刻,每回我们都要拿出来聊几句。
我做游戏开发的时候,有个仓库功能就出现了因为数据库字段类型和代码中字段类型不一致导致的问题。
但是,在系统里面,代币在开始设计计量单位的时候,在数据库里面是decimal类型的,因此一开始这个字段在代码中的定义也是decimal。
可是,后来经过公司研究,觉得代币本来就是整数,还是整数比较好一点,因为跟代币相关的业务都不带小数点。于是研发经理没有经过仔细考虑,就让运维在数据库里直接把用来存放代币的这个字段改成了整型。
于是,问题就出现了,偶然间我们在巡查数据库的时候,发现有个用户的代币数量惊人!普通代币充值肯定是给不了那么多代币的,代币数量跟他充值的记录又不吻合,于是我们笃定这里面一定有猫腻!
但好在虽然这个用户的代币数量多,可是并没有去消耗代币,所以也没有给公司造成什么损失。
于是我们就查代币来源日志,发现这个用户的代币来源日志竟然有数十万条!按道理说,正常情况下,代币日志不会那么多,那么多日志肯定是有问题的。
好在,日志记录得很明显,显示这个客户每次只兑换0.5个代币,并且,是存在仓库里的,而且时间间隔还特别短,基本上就几十毫秒,感觉像是使用脚本刷的一样!
明眼人一看就知道问题出在哪里了!
后来,事情真相大白,用户主动联系了我们,并告明来意。用户也没隐瞒,直说我们系统有BUG!在将代币存入仓库时,只要将存入数量写成0.5,然后就可以存入1个代币且不扣余额里的代币!
这个BUG是他自己测出来的,虽然刷了那么多代币,但是自己一分没用!
简单得说,这个BUG出现的原因就是业务逻辑中的代币格式和数据库中的代币格式不一致导致的,当然也存在一些代码逻辑问题,这个等下再说。
在数据库中,代币字段的字段类型是整型。因为只改了数据库字段的类型,代码中没有改,因此前端依然可以输入浮点型的数字,并且在业务逻辑层依然能够验证通过。
业务逻辑层通过以后,就到了数据处理这部分,这部分代码依然是没有改的,逻辑本身是正常的,就是首先验证用户账户余额是否足够,然后先减去用户的账户余额再给仓库增加用户代币。
问题就出在这,用户存入的是0.5个代币,在对用户余额进行扣减的时候,因为0.5不是整数,所以扣减后的余额是不变的,然后再给用户仓库增加0.5个代币。此时,数据库对于小数点数据塞入整型字段的时候,默认采取的方案是四舍五入!因此,用户可以在不扣一分钱的情况下,白得一个代币。
之所以出现这种状况,就是因为在执行扣减代币以及增加仓库代币这个Sql语句是写在一条Sql里的,即使在余额扣减失败的情况下,增加仓库代币成功的话,Sql依然会执行成功一条记录!
解决办法当然也很简单,那就是使用事情批处理,任何一个操作执行失败,全部Sql回滚!
这里,用户是比较专业的,他使用了一些劫持工具劫持了我们的客户端和服务端的接口消息,从而能够自己编写脚本去达到他的目的。当然,事后我们跟用户寒暄了几句,向他普了普法,然后没有去追究他的责任。
#程序员# #编程# #计算机#