如何在Spring中为2种不同的方法在2个不同的线程上运行@Async。

时间:2016-06-09 07:13:49

标签: spring multithreading asynchronous spring-async

在我的应用程序中,我有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选择相同的线程并开始处理。

基本上我希望如果审计会抛出任何错误,并且回滚地图更新仍应该发生。

1 个答案:

答案 0 :(得分:0)

我得到了答案。

@Transactional(propagation = Propagation.REQUIRES_NEW)总是在从另一个bean调用时创建一个新事务。

如果从同一个bean调用,则永远不会创建新事务,并且因为它是@Async,所以它在已经运行的异步线程中启动。

所以,我必须为我的方法创建另一个bean,并且这两个方法同时开始在2个不同的线程中运行。

得到我的参考:

  

@Async有两个限制:

     

它必须仅适用于公共方法;   自调用 - 从同一个类中调用异步方法 - 不起作用;

     

原因很简单 - 该方法需要公开才能被代理。   并且自我调用不起作用,因为它绕过了代理和   直接调用底层方法。

http://www.baeldung.com/spring-async