假设现存在一个简单的猜大小游戏,由用户下注大或者小,扣除手续费3%后的钱所有放入奖池中,赢的一方按投注比例平分整个奖池。使用mysql做为数据库,系统精度精确到1位小数。
本文将会讲解其中会出现的业务结算致使的数据问题,以及解决方法。mysql
系统内应该存在一个用户钱包表,其中指定两条记录为系统收入帐户和系统拨出帐户。这样能够将投注的时候,对系统帐户余额增长操做,和发奖的时候,对系统帐户余额的减去操做分离。sql
能够避免上一期游戏的结算,对下一期游戏的投注发生锁等待的问题。数据库
考虑到高并发的状况下,推荐使用mysql自带的排他锁,不推荐乐观锁,由于乐观锁须要重试机制,而队列结算暂时不考虑。
当一名用户发起投注的时候,检查顺序应该以下并发
这里之因此要冗余检查用户的额度,是否了避免开启事务的消耗,防止恶意攻击消耗系统资源,用来开启无心义事务。高并发
奖池额度的97%这里计算须要保持一位精度,若是用户投注是98,按照计算获得的值应该是95.06,咱们应该取95.0而不是95.1,不然你最后存到奖池里面的数就会大于97%,这样系统抽取就不会达到3%,用户少分点不要紧,要保证系统必定能分到3%。设计
简单一句话就是:精度位后都舍弃队列
假设按照投注比例,瓜分出的奖金总数是22.1,A用户的份额是55.5%,A用户拿到12.2655,B用户的份额是45%,B用户拿到9.8345。游戏
这种状况下,你会发现,按照舍弃,原则,分别是12.2和9.8,结果是只发放了22,若是你按照四舍五入原则,才能发放到22.1事务
那为何还要坚持舍弃原则呢?由于,假设出一个极端状况,当你碰到A的值是12.05,B的值是9.05,按照舍弃原则,总数的确仍是22.1。可是按照四舍五入原则,发放的总值就是22.2了。资源
在计算机系统内,浮点数的计算自己就是不可靠的,在业务内应该用整形去避免,当设计到百分比操做的时候,请尽可能使用舍弃原则,保证很少发。按照舍弃原则,给用户少发0.05这种精度外的值,对业务来讲可有可无。若是超发了,会致使系统内帐目混乱,后果将不堪设想。