【发布时间】:2015-12-14 14:05:12
【问题描述】:
如果我们在 grails 中的域对象(例如我们的 Session 对象)上添加 afterUpdate 事件代码:
- 它是在提交更新后调用,还是在刷新后调用,或其他?
- 如果更新失败(例如约束、乐观锁失败),是否还会调用 after 事件?
- afterUpdate 会与更新在同一个事务中吗?
- 进行更新的服务方法的提交是否会等到 afterUpdate 方法完成,如果是,有什么办法可以解决这个问题(创建新线程除外)?
我们有许多在多个 tomcat 上运行的 grails 应用程序实例。每个都有一个会话过期石英作业来过期我们的会话(域对象)
这项工作基本上说 getAllSession 和 lastUpdated > xxx,然后循环调用 session.close(Session.Expired)
Session.close 只是将 session.status 设置为 Expired。
理论上,同一个会话可以同时关闭两次购买在两台服务器上运行的作业,但这并不重要(目前)
现在我们想要自动提现会话过期(或终止)的客户。提现过程需要调用外部支付系统,这可能需要长达 1 分钟的时间,并且可能会失败(但不应阻止会话关闭或“锁定”其他会话)
如果我们在会话域对象上使用 afterUpdate,我们可以检查 session.status,并在交易之外或在另一个线程中(例如使用 Executors)触发兑现。但这是非常危险的——因为我们不知道确切的行为。例如。如果更新失败,它还会尝试执行 afterUpdate 调用吗?我们假设是这样,因为我们猜测提交要到以后才会发生。
另一个未知数是调用保存和提交如何与乐观锁定一起工作。例如。如果您调用 save(flush=true),但没有返回错误,您是否保证提交将起作用(使数据库崩溃),或者是否存在可能失败的情况?
【问题讨论】:
标签: events grails grails-orm