我有一个@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提交错误报告之前,我想我会给你们一些机会指出一些问题。非常感谢提前!