救急,SpringMVC非Controller类中使用任务列队操作service无法连接数据库?

问题:
在任务列队中使用Service操作数据库报错:

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$$bde940af.queryByOrderNo(<generated>)
    at com.superior.chalk.task.WxPayNotifyTask.doInvoke(WxPayNotifyTask.java:25)
    at com.superior.chalk.task.queue.TaskQueueService$1.run(TaskQueueService.java:32)
    at java.lang.Thread.run(Thread.java:748)
    at java.util.concurrent.Executors$RunnableAdapter.call$$$capture(Executors.java:511)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.sql.SQLException: interrupt
    at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1405)
    at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1248)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4619)
    at com.alibaba.druid.filter.FilterAdapter.dataSource_getConnection(FilterAdapter.java:2745)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4615)
    at com.alibaba.druid.filter.logging.LogFilter.dataSource_getConnection(LogFilter.java:876)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4615)
    at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4615)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1226)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1218)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:90)
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:246)
    ... 19 more

调用代码:
1junit test method:
图片说明
2 TaskQueueService

@Component
public class TaskSerialQueueService {
    // 日志监控
    private static final Logger log = Logger.getLogger(TaskSerialQueueService.class);
    //任务列队
    private final LinkedBlockingDeque<TaskQueueHandler> tasks=new LinkedBlockingDeque<>();
    //单线程执行器
    private ExecutorService service= Executors.newSingleThreadExecutor();
    // 检查服务是否运行
    private volatile boolean running = true;
    //线程状态
    private Future<?> serviceThreadStatus = null;

    @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;
                    }
                }
            }
        }));
    }
        ......

2 WxPayNotifyTask具体任务执行器
图片说明

在Junit测试中使用new Thread(new Ruanable(){
在run中操作service也一样报错。
})

2个回答

需要看 TaskQueueService 类的代码,定时任务中注入 Spring 托管的对象时,由于它们部署时不是被容器管理的,依赖实例可能不会被自动注入。需要手动用 BeanFactory 的 getBean 方法获取。

leifengpeng
fplei 你好,TaskQueueService是列队服务类,我把代码重新贴一下
6 个月之前 回复

啥数据库? 驱动啥版本?数据库服务打开了?

leifengpeng
fplei 你好,mybaties+druid+mysql5.7 我在junit当中可以正常操作service,但是一旦在子thread中就会出现以上问题
6 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问