我怎样才能让 @Async 在 Spring. 中的 2 种不同方法的 2 种不同线程上工作?
How can I have @Async work on 2 different threads for 2 different methods in Spring.?
在我的应用程序中,我有 2 个 @Async
方法:一个用于审计目的,另一个用于更新 2 个完全不同的 bean 中的一些映射,从不同的 bean 但同时调用。一个来自审计侦听器,另一个来自控制器。
我的问题是它们都 运行 在一个线程中,即首先审计 运行s 然后在同一个线程中创建这些映射。因此,如果审计抛出一些异常,则不会创建地图,或者地图抛出错误,则不会记录审计。
有什么办法,我可以在不同的异步线程中使用这两种方法运行。
方法一:
@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());
}
方法二:
@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.
都是新手
我的配置 class 有
<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>
在使用 @Async(value="myExecutor")
添加上述配置后,我的代码完全停止工作,我的意思是,定义了 regenerateZoneMapAsync()
的 bean 不是从我的调用 bean 调用的,一些代理问题出现。
编辑:
我想到的一件事是,Audit 线程是否可以完成其处理并将线程发送回池,然后 map 选择相同的线程并开始其处理。
基本上我希望如果审计抛出任何错误,回滚映射更新应该仍然发生。
好吧,我得到了答案。
如果从另一个 bean 调用,@Transactional(propagation = Propagation.REQUIRES_NEW) 总是创建一个新事务。
如果从同一个 bean 调用,则永远不会进行新事务,并且由于它是 @Async ,它会在已经 运行 的异步线程中启动。
所以,我不得不为我的方法制作另一个 bean,并且这两个方法在 2 个不同的线程中同时启动 运行。
我的参考来自:
@Async has two limitations:
it must be applied to public methods only;
self invocation – calling the async method from within the same class – won’t work;
The reasons are simple – the method needs to be public so that it can be proxied.
And self-invocation doesn’t work because it bypasses the proxy and
calls the underlying method directly.
在我的应用程序中,我有 2 个 @Async
方法:一个用于审计目的,另一个用于更新 2 个完全不同的 bean 中的一些映射,从不同的 bean 但同时调用。一个来自审计侦听器,另一个来自控制器。
我的问题是它们都 运行 在一个线程中,即首先审计 运行s 然后在同一个线程中创建这些映射。因此,如果审计抛出一些异常,则不会创建地图,或者地图抛出错误,则不会记录审计。
有什么办法,我可以在不同的异步线程中使用这两种方法运行。
方法一:
@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());
}
方法二:
@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.
都是新手我的配置 class 有
<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>
在使用 @Async(value="myExecutor")
添加上述配置后,我的代码完全停止工作,我的意思是,定义了 regenerateZoneMapAsync()
的 bean 不是从我的调用 bean 调用的,一些代理问题出现。
编辑:
我想到的一件事是,Audit 线程是否可以完成其处理并将线程发送回池,然后 map 选择相同的线程并开始其处理。
基本上我希望如果审计抛出任何错误,回滚映射更新应该仍然发生。
好吧,我得到了答案。
如果从另一个 bean 调用,@Transactional(propagation = Propagation.REQUIRES_NEW) 总是创建一个新事务。
如果从同一个 bean 调用,则永远不会进行新事务,并且由于它是 @Async ,它会在已经 运行 的异步线程中启动。
所以,我不得不为我的方法制作另一个 bean,并且这两个方法在 2 个不同的线程中同时启动 运行。
我的参考来自:
@Async has two limitations:
it must be applied to public methods only; self invocation – calling the async method from within the same class – won’t work;
The reasons are simple – the method needs to be public so that it can be proxied. And self-invocation doesn’t work because it bypasses the proxy and calls the underlying method directly.