3

我们在网页游戏中有一个按钮供用户收集奖励。应该只单击一次,在收到请求后,我们会将其标记为在 DB 中收集。

我们已经阻止了客户端中的按钮重复点击。但是,如果人们在短时间内将包裹多次重新发送到我们的服务器,那将无济于事。

我想要的是一种从服务器端阻止它的方法。

我们在服务器端使用 Playframework 2 (2.0.3-RC2),到目前为止它是无状态的,我很想像这样使用 Set 来保护:

if processingSet has userId then BadRequest
else put userId in processingSet and handle request
     after that remove userId from that Set

但是后来我不得不面对像更新Scala集合线程安全的问题,并且一旦我们在负载平衡后面有多个服务器,仍然无法阻止用户。

我正在考虑的一种可能性是在 DB 中有一个表来代替上面的 processingSet,但这会导致每个请求 1+ DB 操作,有没有更好的解决方案~?

谢谢~

4

2 回答 2

3

在这种情况下,额外的数据库操作是相对“便宜”的解决方案。如果您打算永久保存按钮状态,则应该使用它。

如果按钮仅在一段时间内被禁用(例如直到游戏结束),您也可以考虑使用缓存 API,但请记住,这不适用于应该长时间存储的解决方案(它不应该是被视为数据库替代品)。

于 2012-08-08T12:26:45.020 回答
3

鉴于您使用的是 Mongo,因此没有跨越单独集合的事务,我认为您可能可以使用原子操作来实现这个守卫- 即“如果当前更新”,这实际上是 CompareAndSwap。

假设您有一个像“rewards”这样具有“collected”属性的集合,您可以将collected标志更新为true,仅当它当前为false并且该操作没有失败时,您可以继续应用奖励知道对于任何其他请求,相同的操作将失败。

于 2012-08-08T15:50:22.110 回答