如何防止php中两个独立的ajax调用修改同一个数据库
how to prevent two separate ajax calls in php from modifying the same database
我得到了一个javascript客户端,它有时会在几毫秒内向(php)服务器发送两个ajax请求。(这是一个javascript错误,我无法从客户端控制,只能从服务器端控制)。
第一个请求检查数据库中是否已经存在凭证(给定几个参数..即客户id等)。。如果凭证已经存在,它只会重新使用凭证并更新其值;如果不存在,它会从头开始创建一个新的凭证。
问题是,在它检查完凭证是否存在之前。。第二个请求进入并检查代金券是否也存在。。此时,第一个还没有创建代金券。。
长话短说。。我们最后得到两张重复的代金券。。(数据库没有限制凭证名称的唯一性。我也无法控制数据库)。。
那么,如何防止第二个ajax请求做任何事情,直到第一个完成它的任务?
请记住,这两个请求是两个不同的线程。。因此,如果我生成任何$isVoucherCreateonProgress变量,它将是无用的,因为第二个调用将完全忽略它。
想法?
如果两个ajax请求来自同一个客户端,则在服务器端创建一个类似锁的系统,因此,如果有人检查了代金券的存在,则设置一个会话变量,直到它完成它必须做的事情。因此,当第二行出现时,它首先检查会话,如果(其他人正在使用代金券)稍后通过消息检查完成,因此,在客户端,当消息被拒绝时,您可以简单地延迟1秒发送,以确保没有人"工作"。
希望这能有所帮助。
或者,您可以看到这个问题,以便在php中生成互斥:php互斥(mutex)
就我个人而言,我会想到一个非常简单的方法。在您的服务器上,您必须有一个创建代金券的过程。保留一个全局数组,在创建凭证之前,将数组的索引设置为id,就像key=>Value一样,其中key可能是凭证的id,Value可能是"正在创建"之类的状态。创建凭证后,您可以使用凭证的id作为关键字删除条目。
现在,每次在创建凭证之前,只需从密钥的全局数组中检查是否已经存在,如果是并且Value="正在创建",那么实际上,您实际上正在创建凭证,因此您退出
希望它能有所帮助,:-)
使用事务。如果你真的不能接触数据库(甚至不能做出自己的声明),你可以使用STM或类似的东西。锁也不会太难,但无论哪种方式都需要您的应用程序持续运行。您可以使用phpdaemon之类的软件运行服务器,并将特定路径转发到该服务器,以获得该连续性。
我知道您在数据库的一个表中创建了一个新行。
应该添加一个唯一性约束,这样就不能添加两次。您是否可能必须创建多个代金券?你能提供更多信息吗?
关于更新,您应该在行中添加一个"版本"字段。客户端需要具有正确的版本号才能更新行。因此,它避免了不需要的并发更新问题。这是ORM的最佳实践,您可以查看此项以寻找"乐观更新"。
由于您无法控制数据库,请在服务器中创建一个请求缓存(即静态对象),并在缓存中创建/更新一行(如果需要,则与此客户+其他参数有关)(例如http://www.php.net/manual/en/book.memcache.php)。您的缓存应该在一段时间内自行清理(我想php中有缓存解决方案)。
另一个想法(很难看,但因为你的解决方案似乎太有限了):放慢速度。等待足够的时间以确保没有其他人(你需要一个循环,如果需要的话,它会检查并撤消——随机收敛)。
您可以在ajax请求启动时设置一个标志(用JavaScript)-检查是否已设置,然后返回,也可以将ajax请求更改为同步。
- 无法在通过jQuery的ajax加载的页面中执行javascript
- 如何通过ajax刷新JSF填充的javascript变量
- 如何使jQuery插件函数可调用以供独立使用,而不在集合上操作
- 如何在php文件中获取$.post-ajax传递的值
- Replacing $ .ajax?
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- Ajax发布表单序列化,发布引号'
- 通过Ajax将JavaScript函数传递给PHP文件
- ajax请求的顺序总是不同的
- 可以't使用Polymer's的核心ajax
- Ajax Live搜索发布到Laravel视图
- Ajax聊天消息重复而不仅仅是更新
- 从控制器返回后Ajax启动事件激发
- 如何防止php中两个独立的ajax调用修改同一个数据库
- AJAX的独立库
- 同时独立的AJAX请求
- 我的独立php文件如何从ajax后接收数据
- 使用尽可能多的独立线程检索5个图像- jquery ajax
- 为ajax请求建立独立的服务器会话
- Ajax vs独立页面:如何处理按'back'