阿贾克斯通话面临尴尬局面

Posted

技术标签:

【中文标题】阿贾克斯通话面临尴尬局面【英文标题】:Ajax call facing an awkward situation 【发布时间】:2017-01-19 09:04:15 【问题描述】:

请给我一个很长的问题......

我必须将一条数据库记录添加到一张主表中,比如说test 表。在向该表添加记录后,我想要它的last inserted id,然后想在事务表中添加大约 1000 个条目(同时向这 1000 条记录发送 EMAILS),比如说test_transaction 表。

但是第二个操作,将记录添加到事务表中,需要更多的秒来将记录添加到数据库。我正在使用客户 MVC,我的代码看起来像...

public function addtotest()

    $strSql = "INSERT INTO test ...";
    $intId = $this->db->execute($strSql);

    foreach($arrTransaction $transact)
    
        $strSql = "INSERT INTO test_transaction ...";
        $this->db->execute($strSql);
    

    echo $intId;

所以我想将test_transaction 表的条目放入另一个action,如下所示

public function testtrancation()

    $id = $_REQUEST['id']; //It's understood that I am doing proper validation here
    foreach($arrTransaction $transact)
    
        $strSql = "INSERT INTO test_transaction ...";
        $this->db->execute($strSql);
    

所以主要问题,我从AJAX 调用addtotest 操作,当它给出id 作为响应时,我想调用另一个AJAX,它将近似1000 记录添加到数据库。

但我不想让用户再等待几分钟以获取 1000 记录,从而影响用户体验。

    所以我正在通过addtotest `AJAX' 调用添加记录后重新加载页面。 呼叫另一个AJAX 呼叫success of addtotest

    在调用testtransactionAJAX 之后,我正在重新加载我的页面。

    $.ajax(
    
        url: SERVER_PATH + 'addtotest',
        type: 'post',
        async: true,
        data:  required_data: required_date ,
        success:function(data)
        
            alert('Record added successfully.');
    
            //I DO NOT WANT USERS TO WAIT FOR THIS AJAX CALL
            $.ajax(
            
                url: SERVER_PATH + 'testtransaction',
                type: 'post',
                async: true,
                data:  intId: data.id ,
                success:function(data)
                
                //DO NOTHING
            ,
            );
            //I DO NOT WANT USERS TO WAIT FOR THIS AJAX CALL
    
            location.reload();
        ,
    );    
    

但是随着页面重新加载,我的 AJAX 调用也会在未完成 AJAX 请求的情况下消失。

那么在这种情况下可以做到吗?如果您想了解更多详细信息,请告诉我。

我不希望用户等待另一个 1000 条目(以及向这 1000 条记录发送 EMAILS)被写入数据库。

【问题讨论】:

@NeilA,非常感谢您改进问题。 很高兴能提供帮助 我从未使用过它们,但是使用 Ajax 调用 start a cronjob 怎么样? 在测试表上插入数据时,可以在redis上发布事件,即使使用节点js也可以监听。 您为什么要让客户参与您的第二千次插入?为什么还要涉及 php?如果千次插入 100% 依赖于最后一个插入 ID,那么您可能可以在 mysql 存储过程中完成所有操作! 【参考方案1】:

这很简单!

单次插入后可以调用单独的后台进程:

public function addtotest()

    $strSql = "INSERT INTO test ...";
    $intId = $this->db->execute($strSql);
    exec('php /your/php/cli/script.php param1 param2 paramN 1>> /dev/null 2>> /dev/null &');
    echo $intId;

“&”进程在后台启动,因此您可以继续,而不必等到脚本完成。

或者您可以将此作业添加到“延迟任务”中并使用 cron 运行此任务。

【讨论】:

我的 MVC url 可以与 exec 一起使用吗?就像我有网址SERVER_PATH . "controller/addtotest/id/1 不知道你的框架。但是很多框架都支持 CLI 模式。比如:/usr/bin/php /path/do/cli-index.php -q controller/addtest/id/1 @NullPointer 或...您可以使用 curl 或 wget 调用您的站点,例如: exec('wget domain.tld/controller/addtotest/id/1 1>> /dev/null 2>> /dev/null &') ,但这并不安全。因为,也许这个动作需要 auth/login。 是的,但我认为在同一个站点中使用 cURL 是可取的?我不能从客户端调用任何东西,其余的工作会自动完成而不会让用户等待吗? @NullPointer, & 进程在后台启动,因此您可以继续,不必等到脚本完成。【参考方案2】:

不要为此使用 AJAX。您需要具有基本分页功能的 CRONJOB。

在一个 php 文件中提取 ID 并在每个序列的每 500 个请求的列表序列之后。并在接下来的 500 处使用 header() 重定向,直到您到达终点。不会影响用户体验,ypu会有很好的表现。

【讨论】:

【参考方案3】:

您可以使用一个 sql 查询插入所有行。

INSERT INTO test_transaction (col1, col2)
VALUES (value11, value12),
(value21, value22),
(value31, value32),
...
(value10001, value10002);

【讨论】:

【参考方案4】:

然后创建一个数据库触发器。 所以当记录被插入第一个表时 它插入事务表或 SO。

示例 -

    CREATE TRIGGER trg_Table1_INSERT
 ON dbo.Table1 AFTER INSERT 
AS BEGIN
   INSERT INTO dbo.Table2(SerialNo, Name)
  SELECT SerialNo, Name
  FROM Inserted

   INSERT INTO dbo.Table3(SomeOtherCol)
  SELECT SomeOtherCol
  FROM Inserted
END

【讨论】:

我认为我们无法在触发器中获取请求信息。我说的对吗? 我猜我们不需要请求信息。我们只需要 Insert.See Updated 的 id。 添加trigger 是个好主意,我不需要在前端等待它。

以上是关于阿贾克斯通话面临尴尬局面的主要内容,如果未能解决你的问题,请参考以下文章

视频通话中「最尴尬」的声音,七牛云帮你解决了

35岁的尴尬年龄,面临“前有强敌,后有追兵“,中年软件测试员的N种可能

35岁的尴尬年龄,面临“前有强敌,后有追兵“,中年软件测试员的N种可能!

35岁的尴尬年龄,面临“前有强敌,后有追兵“,中年软件测试员的N种可能

IT新人面临最尴尬的事:需工作累计经验,有经验才能找到工作!

中国的 GitHub 要来了?