Grails:不管success/failure如何存储审计记录?

Grails: Store audit record regardless of success/failure?

在 Grails 中,无论事务如何结束,为某些操作编写审计记录的推荐模式是什么?示例:由于多种原因可能会失败的在线用户注册尝试。

基本假设,业务逻辑仅限于事务服务方法。

潜在的不确定性:我是否应该通过在服务中抛出 RuntimeException 来中止事务? Grails 指南有点暗示是这样,但是 Burt Beckwith once said(轻笑,我敢肯定)这就像用锤子敲打自己,让自己得到一些照顾。

考虑到冗长的逻辑和多次检查,当检测到冲突时抛出异常很方便。应该回滚整个事务,但是还是要写一条审计记录。

N.B。有几个审计 Grails 插件,但它们记录对提交的域对象的更改。

在我们的应用程序中,我们为此使用了 Platform Core 插件。基本上,当一些有趣的事情发生时,例如:

  • 用户登录
  • 新用户注册
  • 用户创建了一些业务对象的新实例
  • 用户删除了一些东西
  • 等...

我们触发一个事件,如下所示:

event(
    'myApp.activity', [
    userId: userService.currentUser?.id,
    detail: [name: "some useful information about this activity", timestamp: new Date(), ...],
    activityType: ActivityType.CREATED,
    action: "create",
    ...
])

然后我们可以在另一个服务 class 中定义方法来侦听其中的一些事件,例如

@Listener(topic="myApp.activity")
def audit(parameters) {
    //create an audit record for the thing that just happened
}

好处是

  • 它使审计逻辑等交叉内容远离应用程序的其余逻辑
  • 审计是在一个单独的线程中执行的(因此它不涉及与触发事件的事物相同的事务)
  • 您可以将多个侦听器方法分配给一个 activity,以便您以后可以选择扩展应用程序