我在同一个Spring bean中有两个基于Spring的异步线程池和方法。 doWork()
使用默认的Spring线程池,holdAndReprocess()
使用自己的Spring线程池。
我目前的类设置如下,其中doWork
处理一些工作,然后如果发生故障,它将线程停放在holdAndReprocess()
"队列"线程池,然后通过调用doWork()
等待并重新处理线程。使用我当前的设置,对holdAndReprocess()
的调用然后回调到doWork()
的调用是同步的。关于如何连接这个问题的任何想法,以便doWork()
和holdAndReprocess
之间的所有通信都是异步的?
我使用的是xml支持的配置,而不是纯粹的注释驱动的Spring bean。
public class AsyncSampleImpl implements AsyncSample {
@Async
public void doWork(){
holdAndReprocess();
}
@Async("queue")
@Transactional(propagation = Propagation.REQUIRED)
public void holdAndReprocess(){
//sleeps thread for static amount of time and then reprocesses
doWork();
}
}
答案 0 :(得分:0)
阅读https://stackoverflow.com/a/4500353/516167
当您从同一对象中的另一个方法调用@Async方法时,您可能绕过异步代理代码并只调用普通方法,即在同一个线程内。
将此bean拆分为两个bean,并从单独的bean调用holdAndReprocess()
。
此规则也适用于@Transactional
注释。
了解这一点:https://stackoverflow.com/a/5109419/516167
来自Spring Reference Documentation Section 11.5.6, “Using @Transactional”
在代理模式(默认设置)下,只有'外部'通过代理进入的方法调用将被截获。这意味着自调用'即目标对象中调用目标对象的其他方法的方法,即使调用的方法标记为,也不会在运行时导致实际的事务。
@Transactional
!
草案
public class AsyncSampleImpl implements AsyncSample {
public void doWork(){
reprocessor.holdAndReprocess();
}
public void holdAndReprocess(){
//sleeps thread for static amount of time and then reprocesses
worker.doWork();
}
}