Unless you're using JTA, your first approach is not reliable. What if you send the email and the currently running transaction rolls back?
Fortunately, you don't have to use JTA. You need to send the email only after the transaction has been committed. This is fairly easy to do since you need a non-transactional service to coordinate the first @Transactional Repository and the EmailService.
MyBusinessService - not-@Transactional
-> MyRepositoryService - @Transactional
-> MyEmailService not-@Transactional
This way, when the call exists the @Transactional Repository service, you are sure that the database transaction has been committed.
This way, the Email Service can send the email asynchronously, which is a good approach since it allows you to reduce the overall response time.
My friend, Michale Simons, already has an example for this on
GitHub. Enjoy!