fplei 2019-10-11 17:26 采纳率: 0%
浏览 220

救急,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条回答 默认 最新

  • 毕小宝 博客专家认证 2019-10-11 18:19
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥15 krpano-场景分组和自定义地图分组
  • ¥15 lammps Gpu加速出错
  • ¥15 关于PLUS模型中kapaa值的问题
  • ¥15 关于博途V17进行仿真时无法建立连接问题
  • ¥15 机器学习教材中的例题询问
  • ¥15 求.net core 几款免费的pdf编辑器
  • ¥15 为什么安装HCL 和virtualbox之后没有找到VirtualBoxHost-OnlyNetWork?
  • ¥15 C# P/Invoke的效率问题
  • ¥20 thinkphp适配人大金仓问题
  • ¥20 Oracle替换.dbf文件后无法连接,如何解决?(相关搜索:数据库|死循环)