简体   繁体   English

调用控制器操作时 Grails 视图挂起

[英]Grails view hangs when calling a controller action

I have a view that has a link using the g:link gsp tag with action that runs and update on a significant number of rows, so it takes some time.我有一个视图,其中包含一个使用g:link gsp 标记的g:link ,其中包含在大量行上运行和更新的操作,因此需要一些时间。 In the mean time the browser is in limbo and times out after 30 sec (which is the timeout on the servlet container).与此同时,浏览器处于不确定状态,并在 30 秒后超时(这是 servlet 容器的超时时间)。

Problem:问题:

  1. It is a bad user experience that the page times out.页面超时是一种糟糕的用户体验。
  2. The browser submits the controller action each time the timeout occurs.每次超时发生时,浏览器都会提交控制器操作。 I have handled this by checking if the query is already running so this is no longer an issue.我通过检查查询是否已经在运行来处理这个问题,所以这不再是一个问题。

Question:题:

How can I trigger the controller action and reload the page to the same view.如何触发控制器操作并将页面重新加载到同一视图。 Or is there a better way to handle this like triggering the action async?或者有没有更好的方法来处理这个问题,比如触发异步操作?

I tried to reload the page using js, but it does not seem to reload the page.我尝试使用 js 重新加载页面,但它似乎没有重新加载页面。 I have read about implementing a message queue, but it seems like a lot of work for a simple issue.我已经阅读了关于实现消息队列的内容,但对于一个简单的问题似乎需要做很多工作。 Any ideas will be good.任何想法都会很好。 Thank you in advance.先感谢您。

View:看法:

<li>
  <a class=""
     href="${g.createLink(controller: "hello", action: "dbAction")}">Run Update on DB
  </a>
</li>

Controller Action:控制器动作:

def dbAction() {
        some code...
        myservice.dbAction();
        redirect(action: 'index')progress"
        }
    }

My Service dbAction:我的服务 dbAction:

def dbAction() {
    Sql sql = getSql()
    sql.executeUpdate('''
    update mytable
    set
        mydata = calculate_data,
        updated_by = 'dbAction',
        updated_at = now()
    where
        id in (1,2,3)
}

I have exactly your problem.我正好有你的问题。 The query takes so long to run, the controller cannot respond back to the browser.查询运行时间太长,控制器无法响应浏览器。 So, the browser times out.因此,浏览器超时。

I tried 3 different ways to fix this.我尝试了 3 种不同的方法来解决这个问题。

The easy way out: I am using Tomcat.简单的出路:我正在使用Tomcat。 So, I set the connection timeout value longer.因此,我将连接超时值设置得更长。 The connectionTimeout variable is in the server.xml file. connectionTimeout 变量位于 server.xml 文件中。

The lazy way out: I don't know if Grails has any sort of Message Queue function or not.懒惰的出路:我不知道 Grails 是否有任何类型的消息队列功能。 So, I rolled my own.所以,我推出了自己的。 When I click the submit button to run a very long update query, the action will INSERT INTO a sort of update command in a database table along with the state.当我单击提交按钮运行一个很长的更新查询时,该操作将在数据库表中插入一种更新命令以及状态。 I then use Quartz to schedule maybe every 10 seconds to read this table to check the state.然后我使用 Quartz 安排可能每 10 秒读取此表以检查状态。 If the state is NEW, I change the state to "IN PROGRESS".如果状态为 NEW,我将状态更改为“IN PROGRESS”。 And then I let the trigger to run the update query in the background.然后我让触发器在后台运行更新查询。 After it finish, I change the state to FINISH.完成后,我将状态更改为 FINISH。

So, the action is just adding a row to the database and then respond back the view that says something like... You have issued the request.因此,该操作只是向数据库中添加一行,然后响应显示类似...的视图,您已发出请求。 The system will process your request in a few moment.系统将在稍后处理您的请求。

The hard way out: I went over all my SQL and functions in the actions to calculate the time it will take the SQL and codes to finish the query.艰难的出路:我检查了我所有的 SQL 和操作中的函数,以计算 SQL 和代码完成查询所需的时间。 I then rearrange/rewrite the functions and procedures.然后我重新排列/重写函数和过程。 I am not good enough for this.我对此还不够好。 If I can get to O(n), that will be enough for me.如果我能达到 O(n),那对我来说就足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM