Why TransactionalEventListener is not working in transaction?

Viewed 85

I have implemented event publisher, but it doesnt work as I expect. I try to configure events publishing only for successful transaction commit asynchronously.

Example of usage:

    @Transactional(readOnly = true)
    public FooDto getFooByUuid(final String uuid) {
        ...findFooByUuid(uuid)...
        auditClient.publishEvent(new Event(foo)); // published only if transaction didn't rolled back.
        ... some code
        return fooDto;
    }

I have the following config.

@Configuration
@EnableAsync
public class ApplicationConfig implements AsyncConfigurer {


    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new CustomAsyncExceptionHandler();
    }

    @Bean(name = "publishPoolTaskExecutor")
    @Primary
    public Executor publishPoolTaskExecutor() {
        final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("publisher-");
        executor.initialize();
        return executor;
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

and I have AuditClient

...
    @Async(value = "publishPoolTaskExecutor")
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void publishEvent(EventDto<?> event) {
    try {
                String eventString = objectMapper.writeValueAsString(event);
                String response = restTemplate.postForEntity(
                    url,
                    eventString,
                    String.class
                ).getBody();
                log.info(response);
            } catch (Exception e) {
                ...
            }
     }

When exception is thrown in getFooByUuid method - event still publishes. How should I configure publishEvent method, that will be executed ONLY in case transaction successfully committed.

0 Answers
Related