@TransactionalEventListener(fallbackExecution = true)在提交之前运行

时间:2017-09-07 10:43:37

标签: java spring events asynchronous transactions

我有一个@Service类,它在Spring @Transactional方法中运行一些逻辑。

该方法"完成" a通过将isCompleted标志设置为true来进行处理。

然后更新数据库中的Process并启动ProcessCompletedEvent。

使用@TransactionalEventListener(fallbackExecution = true)注释的异步 ProcessCompletedEventListener选取已启动的ProcessCompletedEvent,如果已完成的进程数等于1,则执行一些额外的逻辑。

以下是一些示例代码:

@Service
public class ProcessService {

    @Override
    @Transactional
    public Process completeProcess(Process process) throws ServiceException {

        process.setCompleted(true);
        process = processDao.update(process);

        eventPublisher.publishEvent(new ProcessCompletedEvent(process));

        return process;
    }
}

@Component
public class ProcessCompletedListener {

    @TransactionalEventListener(fallbackExecution = true)
    public void doStuffWhenFirstProcess(ProcessCompletedEvent event) {

        Process process = event.getProcess();

        //Thread.sleep(1000) <- Uncomment this, and everything works
        if (processService.getNumberOfCompletedProcesses(process.getUser()) == 1) {

            doStuff();

        }
    }

在我的单元测试中,我使用没有完成进程的新用户运行此操作。理论上,当使用此用户调用completeProcess()时,监听器应调用doStuff(),因为此用户现在只有一个已完成的进程。

问题是当没有Transaction(completeProcess()完成并关闭Transaction)时,一切正常。但是,当有交易时,processService.getNumberOfCompletedProcesses(process.getUser())会返回0。这可能是因为尚未提交将流程更新为完成的事务。

但是,默认阶段为AFTER_COMMIT,情况并非如此。监听器应该等到事务提交然后运行。在那种情况下,测试应该总是通过。

对于它的价值,我使用SimpleApplicationEventMulticaster进行异步事件处理。这一切都按预期工作,事件监听器在新的线程中产生。

我已经用尽所有可能性,我非常担心它们是Spring @TransactionalEventListener中的缺陷。在我向Spring提交错误报告之前,我想我会给你们一些机会指出一些问题。非常感谢提前!

0 个答案:

没有答案