eventsjakarta-eecdi

Jakarta EE CDI Event TransactionPhase.AFTER_SUCCESS event order is reverse


When annotating an observer method with AFTER_SUCCESS, the events are received in the reverse order they actually have been fired during the transaction.

Example pseudo code:

@Transactional
void test(){
    pushEvent.fire( new PushEvent(10) );
    pushEvent.fire( new PushEvent(20) );
    pushEvent.fire( new PushEvent(30) ); 
}

Observer:

void onPushEvent( @Observes( during = TransactionPhase.AFTER_SUCCESS ) PushEvent event ){
   System.out.println(event.getValue())
}

Unexpected, but observed result:

30
20
10

Can this be changed?


Solution

  • Fixed this in my project with a thread-local buffer of events which gets flushed on AFTER_SUCCESS and replays the events in the order they appeared in first place

    ThreadLocal<List<PushEvent>> threadEventBufferHolder = ThreadLocal.withInitial( ArrayList::new );
    
    void onPushEvent( @Observes( during = TransactionPhase.IN_PROGRESS ) PushEvent event ){
        threadEventBufferHolder.get().add( event );
    }
    
    void onPushEventFailure( @Observes( during = TransactionPhase.AFTER_FAILURE ) PushEvent event ){
        buffer.clear();
    }
    
    void onPushEventCommit( @Observes( during = TransactionPhase.AFTER_SUCCESS ) PushEvent event ){
        List<PushEvent> buffer = threadEventBufferHolder.get();
        buffer.forEach( this::doPrintlnValue );
        buffer.clear();
    }
    

    Unrelated code removed for easier reading