问题:我在项目中使用线程池新建了线程列队,controller请求后把耗时任务交给列队处理,
列队中需要service注入,但是在Test中测,子线程无法使用service的方法,代码如下:
TaskQueueHandler.java
public interface TaskQueueHandler {
String getTaskName();
int doInvoke();
}
TaskSerialQueueService.java
...
@PostConstruct
public void init(){
serviceThreadStatus=service.submit(new Thread(new Runnable() {
@Override
public void run() {
while (running){
try{
TaskQueueHandler taskQueueHandler= tasks.take();
if(taskQueueHandler!=null){
try{
taskQueueHandler.doInvoke();
}catch (Exception e){
log.error(taskQueueHandler.getTaskName()+" doInvoke Error!",e.getCause());
}
}
}catch (InterruptedException e){
running=false;
}
}
}
}));
}
/**
* 往列队中添加新任务
* @param taskQueueHandler
* @return
*/
public synchronized boolean addTask(TaskQueueHandler taskQueueHandler){
if(!checkServiceIsActive()){
activeService();
}
boolean success= tasks.offer(taskQueueHandler);
if(!success){
log.warn(taskQueueHandler.getTaskName()+"任务列队添加失败!");
}
return success;
}
...
WxPayNotifyTask.java
public class WxPayNotifyTask implements TaskQueueHandler{
private String orderNo;
public WxPayNotifyTask(String mOrderNo){
this.orderNo=mOrderNo;
}
@Override
public String getTaskName() {
return WxPayNotifyTask.class.getSimpleName();
}
private OrderService orderService;
@Override
public int doInvoke() {
System.out.println("orderNo="+orderNo);
orderService= (OrderService)SpringUtils.getBean("orderService");
try{
OrderBean orderBean=orderService.queryByOrderNo(orderNo);
System.out.println(orderBean.toString());
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
}
测试代码中调用
@Autowired
private TaskSerialQueueService taskQueueService;
taskQueueService.addTask(new WxPayNotifyTask("379991638464417792"));
测试发现报错信息如下
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: interrupt
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:289)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:377)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:461)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:277)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.superior.chalk.service.order.OrderServiceImpl$$EnhancerBySpringCGLIB$$d45a5b10.queryByOrderNo(<generated>)
at com.superior.chalk.task.WxPayNotifyTask.doInvoke(WxPayNotifyTask.java:27)
at com.superior.chalk.task.queue.TaskSerialQueueService$1.run(TaskSerialQueueService.java:35)
at java.lang.Thread.run(Thread.java:745)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: interrupt
最后发现如直接在test中使用
new WxPayNotifyTask("379991638464417792").invoke()是可以使用service的,但是在子线程中能获取到service但调用service的方法就报错。
先谢谢各位大佬帮忙分析分析!