Java / Groovy如何捕捉spring dao系列异常

时间:2016-01-30 14:34:29

标签: spring grails groovy

我使用Grails通过线程池实现多线程进程,每个线程创建并保存域对象Microblog。但似乎只要在任何线程中发生异常,线程池就会被关闭。在我的例子中, org.springframework.dao.DataIntegrityViolationException 导致 java.util.concurrent.ExecutionException ,随后终止我的线程池和所有后续逻辑。

我不希望这种情况发生,所以我想在保存域对象时捕获所有可能的spring和hibernate异常。简而言之,我想知道如何在Spring和Hibernate的框架下捕获可能的异常。

我的多线程是这样的:

ExecutorService es = Executors.newFixedThreadPool(threadCount);
def threads=[];
for(int i=0;i<threadCount;i++){    
    threads.add(new MyThread(params));
}
try {
    //submit all threads to the pool
    List<Future> futures = threads.collect{theThread->
          es.submit({->
            theThread.run();
          });
        }
        futures.each{it.get()}
}finally {
        def notRun=es.shutdownNow();
        log.info "Now the thread pool is shut down. Still ${notRun} threads are not finished and stopped.";
}

在已实现的runnable类中:

public MyThread implements Runnable{
    @Override
    public void run(){
        //some logic here
        Microblog.withTransaction{
            Microblog m=new Microblog(some params);
            try{
                m.save(flush:true);
                if(m.hasErrors()){log.error m.errors}
            }catch(//how to catch spring and hibernate exceptions in one catch?){//Some error handling here. At least the thread lives.
            }
        }
    }
}

欣赏你富有洞察力的想法!

1 个答案:

答案 0 :(得分:1)

尝试使用ThreadGroup.uncaughtException和/或Thread.UncaughtExceptionHandler。

在你的catch块中,你可以捕获所有异常,然后检查它是否是休眠或像春天一样:

catch(Exception e) {
if(e.getClass().getCanonicalName().beginsWith("org.springframework")) {
}
if(e.getClass().getCanonicalName().beginsWith("org.springframework")) {
}
}

其他选项是检查异常类是否是Spring / Hibernate的BaseException接口。 Spring没有它,但您可以尝试org.springframework.core.NestedRuntimeException。对于Hibernate,您可以使用org.springframework.core.NestedRuntimeException。

请注意,如果您只是想捕获所有框架异常,那么为代码生成的异常提供接口可能更好。您可能会捕获该异常,然后是其他异常:

catch(MyException me) {
} catch(Exception e) {
}