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,以便您以后可以选择扩展应用程序
在 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,以便您以后可以选择扩展应用程序