首先,抱歉我的英语不好,我是在谷歌翻译的帮助下写的。
我正在尝试使用 PHP 和 Ajax 制作类似 Google Wave 的应用程序。我有一个 textarea,当用户输入内容时,页面上的 javascript 使用 oninput 检测并将 textarea 的内容发送到服务器,服务器将内容存储到数据库中。
我所做的是,每次我通过 XHR 发送内容时,XHR.abort() 总是会中断之前的 XHR 请求。数据库中的数据很好,但是,有时它存储的是以前的版本。
我知道发生这种情况是因为即使客户端已经中止,PHP 也没有停止执行,有时前一个请求比上一个请求花费更多的时间并在上一个请求之后完成,所以我阅读了函数手册“ignore_user_abort”和“connection_aborted”,但问题仍然存在。
我创建这个脚本来模拟这种情况,我希望当我中止连接(按“停止”,关闭选项卡/窗口)时,数据库中没有任何新数据,但 5 秒后,我仍然有新数据,所以我需要帮助在用户中止连接时回滚事务。
这里是模拟的脚本(定义了 PDO_DSN、PDO_USER、PDO_PASS):
<?php
ignore_user_abort(true);
ob_start('ob_gzhandler');
$PDO = new PDO(PDO_DSN, PDO_USER, PDO_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$PDO->beginTransaction();
$query = $PDO->query('INSERT INTO `table` (`content`) VALUES (' . $PDO->quote('test') . ')');
sleep(5);
echo ' ';
ob_flush();
flush();
if (connection_aborted()) {
$PDO->rollBack();
exit;
}
$PDO->commit();
ob_end_flush();
最佳答案
如果您发现 XHR.abort() 和 connection_aborted() 不可靠,请考虑使用其他方式发送带外信号以通知正在运行的 PHP 请求它不应该提交交易。
你在运行吗 APC (或者你可以)?
代替调用 XHR.abort(),您可以发送另一个 XHR 请求来表示中止。此请求的目的是在 APC 用户缓存中记录一个特殊 key 。此键的存在将向正在运行的 PHP 请求表明它应该回滚。
为了实现这一点,每个 XHR 请求都需要携带一个(相对)唯一的事务标识符,例如作为表单变量。该标识符将随机生成,或基于当前时间生成,并将在初始 XHR 以及“中止”XHR 中发送,并允许中止请求与正在运行的请求相关联。在下面的示例中,事务标识符采用变量 t 的形式。
“中止”XHR 处理程序示例:
<?php
$uniqueTransactionId = $_REQUEST['t'];
$abortApcKey = 'abortTrans_' . $uniqueTransactionId;
apc_store($uniqueTransactionId, 1, 15);
示例修改后的数据库写入 XHR 处理程序:
<?php
$PDO = new PDO(PDO_DSN, PDO_USER, PDO_PASS,
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$PDO->beginTransaction();
$query = $PDO->query('INSERT INTO `table` (`content`) VALUES (' . $PDO->quote('test') . ')');
$uniqueTransactionId = $_REQUEST['t'];
$abortApcKey = 'abortTrans_' . $uniqueTransactionId;
if (apc_exists($abortApcKey)) {
$PDO->rollBack();
exit;
}
$PDO->commit();
您可能仍有时间问题。中止可能仍然来不及停止提交。为了优雅地处理这个问题,您可以修改数据库写入处理程序以记录一个 APC key ,指示事务已提交。然后中止处理程序可以检查此 key 的存在,并发回有意义的 XHR 中止结果以通知客户端,“抱歉,我来晚了。”
请记住,如果您的应用程序托管在多个实时服务器上,您将希望使用共享缓存,例如 memcached 或 redis,因为 APC 的缓存仅在一台机器上跨进程共享。
关于php - 当用户中止连接时回滚事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14886938/
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas
我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和
require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame
因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的