You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grails视图调用controller action时挂起超时问题的优化方案咨询

解决方案

方案1:轻量异步处理(无额外中间件,推荐)

这个方案适配你的需求,不需要引入消息队列,仅用Grails/Spring自带的异步能力即可实现,改动量极小。

步骤1:开启服务方法异步执行

给业务服务dbAction方法加Spring的@Async注解,让方法调用时不会阻塞主线程:
首先在项目启动类/配置类上加@EnableAsync注解开启异步支持,再修改服务代码:

import org.springframework.scheduling.annotation.Async
import org.springframework.stereotype.Service

@Service
class MyService {
    @Async
    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)
        ''')
        // 可在这里新增执行完成后的状态标记,方便前端查询进度
    }
}

步骤2:修改控制器逻辑

控制器不需要等待业务方法执行完成,接收到请求后直接提交异步任务,立刻返回响应即可:

def dbAction() {
    // 你原有判断任务是否正在运行的逻辑直接复用即可
    if (isTaskRunning()) {
        flash.message = "当前已有更新任务正在执行,请稍后再试"
        redirect(action: 'index')
        return
    }
    // 异步调用服务,不会阻塞当前请求
    myservice.dbAction()
    flash.message = "数据库更新任务已提交,执行完成后自动生效"
    redirect(action: 'index')
}

步骤3:优化前端交互

把原来的同步跳转链接改成AJAX异步触发,避免页面卡住无响应:

<li>
  <a href="javascript:void(0)" id="updateBtn">Run Update on DB</a>
</li>
<script>
document.querySelector('#updateBtn').addEventListener('click', function() {
    if (!confirm('确认执行数据库更新?操作耗时较长请耐心等待')) return
    this.textContent = '提交中...'
    this.style.pointerEvents = 'none'
    fetch('${g.createLink(controller: "hello", action: "dbAction")}')
      .then(() => window.location.reload())
      .catch(() => {
          alert('任务提交失败,请重试')
          this.textContent = 'Run Update on DB'
          this.style.pointerEvents = 'auto'
      })
})
</script>

方案2:极低改动临时方案

如果暂时不想改后端逻辑,仅修改前端也能快速解决超时问题:给a标签加target="_blank"属性,点击后会新开浏览器标签页执行任务,原页面不会卡住:

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

缺点是用户需要手动关闭新标签页,体验不如方案1。

可选优化:任务进度提示

如果需要让用户感知任务执行状态,可以新增简单的状态查询能力:

  • 用缓存字段/数据库字段存储任务状态:未运行、运行中、已完成
  • 前端提交任务后,每隔几秒轮询状态接口,任务执行完成后自动刷新页面或者弹窗提示即可

内容的提问来源于stack exchange,提问作者Mo Ziauddin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:54:03