/ / Ritardare l'invio della posta fino al commit della transazione: java, spring, email, transazioni, xa

Ritardare l'invio della posta fino a quando la transazione non si impegna - java, primavera, email, transazioni, xa

Qualcuno ha un buon tutorial o qualche consigliosu come implementare il proprio XAResource? Ho bisogno che il MailSender di Spring sia transazionale, in modo che la posta venga inviata solo una volta che la transazione è stata confermata, e sembra che non ci sia alcun wrapper transazionale esistente.

risposte:

2 per risposta № 1

Se devi solo aspettare il commit, come dici in un commento, puoi indagare usando TransactionSynchronizationManager.registerSynchronization() per attivare l'invio di email al momento del commit.


2 per risposta № 2

Puoi usare a TransactionSynchronizationManager.registerSynchronization (piace gpeche menzionato) con a TransactionSynchronizationAdapter che ha una varietà di metodi che vengono chiamati in varie fasi della transazione corrente. Penso che il metodo più adatto per la domanda sia il afterCommit.

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
super.afterCommit();
sendEmail();
}
});

1 per risposta № 3

Dubito che sia possibile implementare trueXAResource per SMTP. Ci dovrebbe essere il supporto per le transazioni sul gestore delle risorse (server SMTP in questo caso) e non credo che ce ne siano. Direi che la soluzione migliore è il pattern "Last resource commit", che consente a una risorsa non XA di partecipare alla transazione XA Cerca su Google, ci sono molte informazioni. La maggior parte dei server Java EE lo supporta.


1 per risposta № 4

Un'altra opzione accanto a quella menzionata da gpeche, è l'invio di un messaggio JMS transazionale dall'interno della transazione. Quindi lascia che l'ascoltatore di messaggi (come ad esempio un bean MDB) invii l'email.

Un altro trucco in EJB è la pianificazione di un timer daall'interno di una transazione. Il timer è anche transazionale e verrà avviato solo quando la transazione viene confermata. Usa semplicemente un timer con timeout = 0, quindi inizierà immediatamente dopo il commit della transazione.