Delaying sending of mail until transaction commits

2020-04-17 04:07发布

Does anyone have a good tutorial or some advice on how to implement one's own XAResource? I need Spring's MailSender to be transactional, so that the mail will only be sent once the transaction commits, and it seems there isn't any existing transactional wrapper.

4条回答
Lonely孤独者°
2楼-- · 2020-04-17 04:47

I doubt that it's possible to implement true XAResource for SMTP. There should be transaction support on the resource manager (SMTP server in this case) and I don't believe there are any. I would say your best bet is 'Last resource commit' pattern - which allows one non XA resource participate in XA transaction. Search Google, there are plenty of info. Most Java EE servers supports this.

查看更多
虎瘦雄心在
3楼-- · 2020-04-17 04:49

If you just need to wait for the commit, as you say in a comment, you can investigate using TransactionSynchronizationManager.registerSynchronization() to trigger email sending on commit.

查看更多
叛逆
4楼-- · 2020-04-17 05:09

You can use a TransactionSynchronizationManager.registerSynchronization (like gpeche mentioned) with a TransactionSynchronizationAdapter which has a variety of methods that are called at various stages of the current transaction. I think the most suitable method for the question is the afterCommit.

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
    @Override
    public void afterCommit() {
        super.afterCommit();
        sendEmail();
    }
});
查看更多
三岁会撩人
5楼-- · 2020-04-17 05:09

One other option next to the one mentioned by gpeche, is sending a transactional JMS message from within the transaction. Then let the message listener (like e.g. a MDB bean) send the email.

Another trick in EJB is scheduling a timer from within a transaction. The timer is also transactional and will only be started when the transaction commits. Simply use a timer with timeout = 0, so it will start immediately after the transaction commits.

查看更多
登录 后发表回答