Grails和后台任务



用户填写一些表单,在其中设置报表生成的参数。他提交表单,服务器验证参数,向用户返回一切正常的消息,并生成报告。报告生成完成后,用户将收到带有报告链接的电子邮件。

在grails中实现这一目标的正确方法是什么?目前我有一个生成报告的服务,它看起来像这样:

@Transactional
class AnalyticsService {
    ExecutorService executor = Executors.newSingleThreadExecutor()
    def buildExportAndSendMail() {
        executor.execute {
            //GENERATE REPORT AND SEND MAIL. USES GORM.
        }
    }
    @PreDestroy
    void shutdown() {
        executor.shutdownNow()
    }
}

我的控制器操作如下:

def generateReport(ReportParams command) {
    if(!command.hasErrors()) {
        analyticsService.buildExportAndSendMail()
        render([success:true, html:"Your report is being generated."] as JSON)
    } else {
        ...
    }
}

然而,服务在尝试访问域对象字段时抛出错误:

Exception in thread "pool-8-thread-1" 
Error |
org.hibernate.LazyInitializationException: could not initialize proxy - no Session

在grails中,做这件事的正确方法是什么?

这里的问题是您正在创建一个新线程,并且它没有绑定到Hibernate会话。创建一个已经足够容易了。使用哪个域类并不重要。例如:

def buildExportAndSendMail() {
  executor.execute {
    SomeDomainClass.withNewSession { session ->
      //GENERATE REPORT AND SEND MAIL. USES GORM.
    }
  }
}

您可以在文档中阅读有关withNewSession的更多信息。

我可能会添加一个带有grails石英插件的作业:

class ReportJob {
    def execute () {
        // create report
        // mail report
    }
}

然后用触发作业

ReportJob.triggerNow (Map params)

优点是,您不需要显式地处理线程或会话内容。

相关内容

  • 没有找到相关文章

最新更新