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?
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