首页 > 解决方案 > MySQL & Socket.IO – 泛滥数据库 > 重复事务

问题描述

我不知道我应该在哪里发布我的问题及其背后的问题,但我会在这里试一试。

前段时间我有一个小项目,用户可以在想法上花费硬币。这些硬币作为余额存储在我的 MySQL 数据库中的用户帐户中。前端使用常规模块连接到后端socket.io,节点应用程序使用常规mysql模块与数据库通信。

​​​

问题: 不幸的是,过了一段时间我发现有可能使用socket.io连接(或多次打开网站以获得相同的结果)淹没/垃圾邮件节点应用程序以减慢 mysql 查询. 这就是为什么可以花费用户两次或更多的硬币的原因。

正常的工作流程是这样的:

Request to DB
check balance
if balance > 0
    spend coins
        reduce coins in DB
else
    reject

请求结束

如何花两次硬币:(问题

Request to DB
Request to DB
    check balance
    check balance
    if balance > 0
    if balance > 0
        spend coins
        spend coins
        reduce coins in DB
        reduce coins in DB
    else
        reject
Request end
Request end

这样就可以在余额更新之前获得花费硬币的代码。

​​​

问题: 如何防止用户做这样的事情?使用请求限制器仅适用于使用相同 IP 的人,因此 scriptkiddys 应该无法访问我上面提到的内容。使用具有不同 ip 的小型僵尸网络的人呢?

​​​

如果我能找到解决这个问题的方法,我可以重新开始这个项目。

标签: mysqlnode.jssocketsspam-prevention

解决方案


一种解决方案是select for update ... where user = XXX使用check balance.

另一种解决方案是添加一version列。然后get balance and version, (假设 verison 为 n), spend, reduce coins and set version= n+1 where version == n, 则后面的填充失败。在此解决方案中,您应该spend coinsreduce succeeded..

这些只是一般的解决方案,仅供参考,因为我不熟悉 socket.io。


推荐阅读