在我的应用程序中,我有2个@Async
方法:一个用于审计目的,另一个用于更新两个完全不同的bean中的一些映射,从不同的bean调用但同时调用。一个来自Audit监听器,另一个来自控制器。
我的问题是它们都在一个线程中运行,即第一次审计运行,然后在同一个线程中创建这些映射。因此,如果审计抛出一些异常,则不会创建映射,或者映射会抛出错误,审计将不会被记录。
有什么办法,我可以在不同的异步线程中运行这两种方法。
方法一:
@Async(value="myExecutor")
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void regenerateZoneMapAsync(DemandSource ds) {
System.out.println("\n\n********************Current Thread in Async Class*****************" + Thread
.currentThread());
regenerateZmFilesByDs(ds);
System.out.println("\n\n*********Current Thread********" + Thread.currentThread());
}
方法2:
@Async(value="myExecutor")
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void callAudit(DemandSource ds) {
System.out.println("\n\n************Current Thread in Audit Class*********" + Thread
.currentThread());
callAudit(ds);
System.out.println("\n\n***********Current Thread********" + Thread.currentThread());
}
为了我自己的清晰度,添加了println,以了解哪个线程已被执行。我是多线程和Spring的新手。
我的配置类有
<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>
在使用@Async(value="myExecutor")
添加上述配置后,我的代码已完全停止工作,我的意思是,已经定义了regenerateZoneMapAsync()
的bean未从我的调用bean调用,出现了一些代理问题。
编辑:
我想到的一件事是,审计线程可以完成其处理并将线程发送回池,然后map选择相同的线程并开始处理。
基本上我希望如果审计会抛出任何错误,并且回滚地图更新仍应该发生。
答案 0 :(得分:0)
我得到了答案。
@Transactional(propagation = Propagation.REQUIRES_NEW)总是在从另一个bean调用时创建一个新事务。
如果从同一个bean调用,则永远不会创建新事务,并且因为它是@Async,所以它在已经运行的异步线程中启动。
所以,我必须为我的方法创建另一个bean,并且这两个方法同时开始在2个不同的线程中运行。
得到我的参考:
@Async有两个限制:
它必须仅适用于公共方法; 自调用 - 从同一个类中调用异步方法 - 不起作用;
原因很简单 - 该方法需要公开才能被代理。 并且自我调用不起作用,因为它绕过了代理和 直接调用底层方法。