Credo di conoscere la risposta a questo, ma sto cercando eventuali buchi o qualsiasi cosa possa mancare.
Questo è focalizzato su Spring e Java, ma potrebbe davvero applicarsi a qualsiasi stack di programmazione.
Ad ogni modo, abbiamo un tipico livello di servizio annotato con @Transactional
in primavera. Ad esempio, potremmo avere:
EmailService
OrderService
HistoryService
Ora l'utente esegue un'azione che chiama un servizio RESTful
che svolge le seguenti operazioni:
orderService.create(....); // wrapped in @Transactional
historyService.create(....); // wrapped in @Transactional
emailService.emailUser(....); // wrapped in @Transactional (also annotated with @Async)
Mentre tutti questi sono chiamati da un controller (che NON è @Transactional), se il servizio di ordine o il servizio di cronologia falliscono, voglio che entrambi vengano sottoposti a rollback e che il servizio di posta elettronica venga interrotto.
Non mi piace mescolare i servizi. Penso che sarebbe brutto che il servizio ordini chiamasse il servizio di cronologia solo in modo che entrambi si trovassero negli stessi limiti di transazione.
Il mio primo istinto è stato quello di creare un servizio ibrido che avvolgesse entrambi i servizi. Qualcosa come:
@Transactional
public void orderEntryService.create(....) {
orderService.create(....); // STILL wrapped in @Transactional
historyService.create(....); // STILL wrapped in @Transactional
}
In questo modo, il mio controller potrebbe essere:
public String create(...) {
orderEntryService.create(...);
emailService.emailUser(...); // this is @Async
// and will never be called if previous
// orderEntryService.create fails
}
Anche se penso che questo mantenga il mio livello di servizio più pulito, può iniziare rapidamente a sommarsi a classi di servizi "aggregati" ingombranti e smemorati. Come gestirlo?