В событийно ориентированной архитектуре хуки довольно полезны: можно перед коммитом добавлять в транзакцию все события (transactional outbox, все дела), а после коммита — отправлять их в очередь сообщений. Однако стоит помнить, что количество соединений к базе ограничено и делать в них что-то длительное не стоит. И на эти грабли я наступил в процессе разработки, сделав отправку сообщений в RabbitMQ после коммита: соединения долго висели и в итоге кончались.

Один из вариантов решения — подцепиться к соединению и делать операции после его закрытия. Второй вариант — кидать задачку во внутреннюю очередь, и обрабатывать отдельным обработчиком. Первое может быть немного напряжно с точки зрения реализации (но в Exposed мне удалось это сделать). Я в итоге скомбинировал оба подхода. Стоит помнить, что гарантий, что что-то выполнится в хуке после транзакции/закрытия соединения нет (потому что приложение может упасть), поэтому должен быть страховочный механизм.

Уже потом нашел репозиторий-пост, в котором описан практически идентичный случай.