情况
嗨,我正在制作一个数据库驱动的游戏,其中有一个问题,如果用户找到正确的答案,他们有权更改问题(即写一个新问题)。
但这有一个重要的问题,我认为它被称为竞争条件。问题是这样的:
- 用户 1 找到答案
- 提示用户 1 输入新问题
- 在用户 1 提交新问题之前,用户 2 也找到了新答案
- 现在只有运气了,谁提交了新问题。如果用户 2 在用户 1 之后提交问题,则用户 2 的问题会覆盖用户 1 的问题。
现在,我已经通过使用某种信号量解决了这个问题,方法是保留它的timestamp
. 总结它的工作原理是这样的:
- 用户 1 找到答案
- 信号量被保存到数据库中
['user_ip' = 'x.x' , 'time'='y.y' , 'locked'='true']
- 信号量在 t 秒后过期
- 仅当信号量过期时才会接受新问题。
因此,当提交新问题时,应用程序仅在信号量未锁定且当前时间t
比信号量的日期大 (15) 秒时才会接受它。
但是这个也有问题,提示User 2
“你找到了答案,但有人在你之前找到了答案。如果他们没有在 15 秒内提交新问题,你可以更改问题。”
所以新的获胜者必须等待 15 秒,这可能是不必要的。
所以,
我想做的事
我想用秒表(计时器)提示“获胜者”一个表格。当它达到零时,它会解锁信号量,以便新的获胜者可以提交他们的问题。
但是这个解决方案会有这个问题:
如果获胜者在计时器归零之前关闭页面,那么 AJAX 请求将永远不会完成,信号量将被无限期锁定。
userLeave();
因此,如果用户关闭页面,我必须确保我已经调用了该函数。
谷歌建议但人们onbeforeunload
也onunload
抱怨这些功能不起作用。那么,如果用户(获胜者)离开页面,是否有 100% 确定的方式来发送此 AJAX 调用?