You could wrap your transactional PlayerService
- or whatever it is that is responsible for saving the player - with a facade. The PlayerService
could just be responsible for saving the player transactionally - and the facade could be responsible for invoking the PlayerService
and then generating the message. Splitting out the send operation from the PlayerService
would ensure that the Player
is committed before the message is generated. For example:
@Service
public class PlayerServiceImpl implements PlayerService {
@Autowired
private PlayerRepository playerRespository;
@Override
@Transactional
public void savePlayer(PlayerDTO playerDTO) {
Player newPlayer = new Player(playerDTO);
// Responsible for saving the player only
playerRepository.save(newPlayer);
}
...
}
And then that could be wrapped with some sort of facade.
@Service
public class PlayerFacade {
@Autowired
private PlayerService playerService;
public void createAccount(PlayerDTO playerDTO) {
playerService.savePlayer(playerDTO);
// Generate the message after successful save.
// The player would be committed at this point because
// the savePlayer method (and thus transaction) has completed
produceJmsMessage(new PlayerCreatedEvent());
}
}
Client code would then interact with the PlayerFacade
rather than the PlayerService
directly - to ensure that both the player is saved and message sent.