Grails: хранить записи аудита независимо от успеха/неудачи?

Какой рекомендуемый шаблон в Grails для написания записи аудита для определенных действий независимо от того, как завершается транзакция? Пример: попытка онлайн-регистрации пользователя, которая может завершиться неудачно по ряду причин.

Базовое предположение: бизнес-логика ограничена транзакционными методами обслуживания.

Основная неопределенность: следует ли прервать транзакцию, создав исключение RuntimeException в службе? Руководство по Grails подразумевает это, но Берт Беквит однажды сказал (наверное, посмеиваясь), что это все равно, что бить себя молотком, чтобы позаботиться о себе.

Учитывая многословную логику с несколькими проверками, удобно генерировать исключение при обнаружении конфликта. Всю транзакцию нужно откатить, но запись аудита все равно написать.

Н.Б. Существует несколько подключаемых модулей аудита Grails, но они записывают изменения в закрепленных объектах домена.


person sodastream    schedule 31.05.2015    source источник


Ответы (1)


В нашем приложении мы используем для этого подключаемый модуль 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",
    ...
])

Затем мы можем определить методы в другом классе обслуживания, которые прослушивают некоторые из этих событий, например.

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

Преимущества

  • он удерживает сквозные вещи, такие как логика аудита, отдельно от остальной логики вашего приложения.
  • аудит выполняется в отдельном потоке (поэтому он не участвует в той же транзакции, что и то, что вызвало событие)
  • вы можете назначить несколько методов прослушивания одному действию, чтобы у вас был еще один вариант для расширения вашего приложения позже
person rcgeorge23    schedule 31.05.2015
comment
Ясно и архитектурно правильно. Я пойду на это! - person sodastream; 01.06.2015