0

在我的应用程序中,我有 2@Async种方法:一种用于审计目的,另一种用于更新 2 个完全不同的 bean 中的某些映射,从不同的 bean 但同时调用。一个来自审核侦听器,另一个来自控制器。

我的问题是它们都在一个线程中运行,即首先运行审计,然后在同一个线程中创建这些映射。所以,如果审计抛出一些异常,映射不会被创建,或者映射抛出错误,审计不会被记录。

有什么办法,我可以让这两种方法在不同的异步线程中运行。

方法1:

@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 调用的,出现了一些代理问题。

编辑:

我想到的一件事是审核线程是否有可能完成其处理并将线程发送回池,然后映射选择同一个线程并开始其处理。

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

4

1 回答 1

0

好吧,我得到了答案。

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

如果从同一个 bean 调用,则永远不会进行新事务,并且由于它是 @Async ,它在已经运行的 Async 线程中启动。

因此,我不得不为我的方法制作另一个 bean,并且这两种方法开始同时在 2 个不同的线程中运行。

我的参考来自:

@Async 有两个限制:

它只能应用于公共方法;自调用——从同一个类中调用异步方法——不起作用;

原因很简单——方法需要公开才能被代理。而自调用也不起作用,因为它绕过了代理,直接调用了底层方法。

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

于 2016-06-15T04:30:50.070 回答