如何测试@Async异步任务

如何测试@Async异步任务,第1张

spring3支持@Async注解的异步任务,之前大家都是通过使用如线程池来完成,spring3也是使用这种方式,但更简单。

其具体实现在:org.springframework.aop.interceptor.AsyncExecutionInterceptor,是一个方法拦截器,其invoke方法的部分代码如下:

Java代码

Future<?>result = determineAsyncExecutor(specificMethod).submit(

new Callable<Object>() {

public Object call() throws Exception {

try {

Object result = invocation.proceed()

if (result instanceof Future) {

return ((Future<?>) result).get()

}

}

catch (Throwable ex) {

ReflectionUtils.rethrowException(ex)

}

return null

}

})

即把当前任务的调用提交给线程池,很简单。

1、测试无事务的异步任务

这个相对来说比较简单:

1.1、设置任务的返回值为Future:

Java代码

public Future sendSystemMessage(Long[] receiverIds, Message message)

1.2、调用future.get()等待任务结束。

Java代码

Future future = messageApi.sendSystemMessage(userIds, message)

future.get()

这个很简单。

2、测试带事务的异步任务

因为是带事务的,所以异步任务肯定要启动一个线程来执行任务,所以无法在主线程回滚,造成数据会commit到数据库,这在集成测试时肯定是不行的;解决方案是移除异步任务:

2.1、使用spring profile,在测试环境下不执行<task:annotation-driven>即可。

2.2、使用我提供的工具类,在测试时移除异步支持即可:

Java代码

//移除异步支持

if(AopProxyUtils.isAsync(messageApi)) {

AopProxyUtils.removeAsync(messageApi)

}

测试类可以参考MessageApiServiceIT.java

工具类下载 AopProxyUtils.java

3、包级别测试

Java代码

@Async

public void sendSystemMessage() {

sendSystemMessageInner()

}

void sendSystemMessageInner() {

//测试时测试这个方法即可

}

这样测试时测试这个包级别的sendSystemMessageInner方法即可

其实更好的做法是spring内部提供支持,支持这样异步调用的测试。

实现方案

使用TransactionSynchronizationManager在事务提交之后 *** 作

public void insert(TechBook techBook){

bookMapper.insert(techBook)

// send after tx commit but is async

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter()

{

用tornado毕竟是可以做异步request的, 如果你的数据库真的很慢, 不如再开其他的tornado做block数据库 *** 作(你可以用tornado wsgi多线程/多进程形式部署, 也可以用django, flask等), 然后通过API的形式将数据库返回过来. 相当于用tornado给你的数据库 *** 作web化(写内部数据API)

这个是我刚才刚刚想到的, 原理就是用一些独立的进程去做费时的数据库 *** 作, 这样你的主web tornado进程就可以异步畅通, 增加吞吐量. 这样就不需要为各个数据库写驱动了.

如果数据库在不同的机器上, 那么可以考虑将这些独立的数据 *** 作tornado进程在数据库机器上部署. 使用wsgi多线程/多进程的好处是查询可以同时进行, 当然也可能卡死数据库. 使用tornado自己的单进程异步部署的时候, tornado还可以充当一个数据库 *** 作队列的作用.


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9909700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-03
下一篇 2023-05-03

发表评论

登录后才能评论

评论列表(0条)

保存