我正在使用Grails通过线程池实现多线程进程,每个线程创建并保存一个域对象微博。但似乎只要任何线程中发生异常,线程池就会关闭。在我的情况下是 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.";
}
在实现的可运行类中:
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.
}
}
}
}
欣赏你有见地的想法!
最佳答案
尝试使用 ThreadGroup.uncaughtException 和/或 Thread.UncaughtExceptionHandler。
在您的 catch block 中,您可以捕获所有异常,然后检查它是休眠还是 Spring ,如下所示:
catch(Exception e) {
if(e.getClass().getCanonicalName().beginsWith("org.springframework")) {
}
if(e.getClass().getCanonicalName().beginsWith("org.springframework")) {
}
}
其他选项是检查异常类是否是 Spring/Hibernate 的 BaseException 接口(interface)。 Spring 没有,但您可以尝试 org.springframework.core.NestedRuntimeException。对于 Hibernate,您可以使用 org.springframework.core.NestedRuntimeException。
请注意,如果您只是想捕获所有框架异常,那么为代码生成的异常提供一个接口(interface)可能是一个更好的主意。您可以捕获该异常,然后捕获其他异常,如下所示:
catch(MyException me) {
} catch(Exception e) {
}
关于spring - Java/Groovy 如何捕获 Spring dao 系列异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35103020/