捕获多个异常并执行相同的操作

时间:2013-12-06 17:27:47

标签: java spring java-ee

我正在编写一个事务管理系统并捕获6个异常我需要为每个异常回滚事务。现在我在每个块中都这样做,有没有办法集中化,我知道一种方法是从方法中抛出异常。

       catch (RollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicMixedException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicRollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (SystemException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        } catch (SystemException e) {
        if(log.isErrorEnabled())
        {
            log.error(e);
        }
        try {
            trans.rollback();
        } catch (RollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicMixedException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicRollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (SystemException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    } catch (RollbackException e) {
       if(log.isErrorEnabled())
       {
           log.error(e);
       }
        try {
            trans.rollback();
        } catch (RollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicMixedException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicRollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (SystemException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    } catch (HeuristicMixedException e) {
        if(log.isErrorEnabled())
        {
            log.error(e);
        }
        try {
            trans.rollback();
        } catch (RollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicMixedException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicRollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (SystemException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    } catch (HeuristicRollbackException e) {
        if(log.isErrorEnabled())
        {
            log.error(e);
        }
        try {
            trans.rollback();
        } catch (RollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicMixedException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (HeuristicRollbackException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (SystemException e1) {
            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

3 个答案:

答案 0 :(得分:3)

如果您使用的是Java 7,则可以在一个catch中管道异常:

try {
    // code which can throw many kinds of exceptions
}
catch (FooException | BarException | BazException e) {
    // do the common thing!
}

答案 1 :(得分:1)

如果您使用的是Java 7,则可以将所有这些内容减少到此:

try {
    ...
} catch(RollbackException|HeuristicMixedException|HeuristicRollbackException e) {
    if(log.isErrorEnabled()) {
        log.error(e);
    }

    try {
        trans.rollback()
    } catch(RollbackException|HeuristicMixedException|HeuristicRollbackException|SystemException e1) {
        e1.printStacktrace();
    }
}

如果您使用的是Java 6,则选项有限。您可以执行catch (Exception e),但这会捕获任何类型的异常,这不是您想要的。因此,您必须执行instanceof检查以确保您拥有正确的异常,然后throw那些不匹配的异常:

try {
    ...
} catch(Exception e) {
    if(e instanceof RollbackException ||
       e instanceof HeuristicMixedException ||
       e instanceof HeuristicRollbackException) {
        if(log.isErrorEnabled()) {
            log.error(e);
        }

        try {
            trans.rollback();
        } catch(Exception e1) {
            if(e1 instanceof RollbackException ||
               e1 instanceof HeuristicMixedException ||
               e1 instanceof HeuristicRollbackException ||
               e1 instanceof SystemException) {
                e1.printStacktrace();
            } else {
                throw e1;
            }
        }

    } else {
        throw e;
    }
}

答案 2 :(得分:0)

您可以考虑所有这些异常是否属于同一类型,然后,如果它们是,则使它们成为更大的超类的子类。

编辑:我被告知您没有写出这些例外情况。对于迂回方式,您可以使用这些非RuntimeExceptions的事实(因为它们是经过检查的异常)。这可能不是一个好习惯,我建议你重新考虑你的结构。

try{
    ...
catch(Exception e){
    if(e instanceof RuntimeException)
        throw e; //rethrow unexpected exception
    //do the right thing
}

至于重构代码,以下是我注意到的一些事情:

  • commit()抛出的两个异常是回滚异常,表明事务已回滚。
  • rollback()方法不会抛出SystemException以外的任何内容。
  • “事务管理器抛出SystemException,表明它遇到了意外的错误情况,导致未来的事务服务无法继续。” (src)因此,您无法在SystemException之后回滚。

如果你遇到异常,那应该是因为你将解决它所指出的问题(更一般地说,将程序恢复到有效状态),或者你会做某事(比如资源清理或记录)和< em>重新抛出,否则你将停止该程序。

不知道你在做什么的具体细节,我建议:

  • 请勿抓住此级别的SystemException。让它走得更远。
  • 抓住RollbackExceptionHeuristicRollbackException并记录它们,但不要回滚。
  • 抓住HeuristicMixedException并回滚。

我们简化了代码,甚至不知道如何在同一地点捕获多种类型的异常。使用Java 7's two enhancements to exceptions,我们可以通过执行您想要的操作进一步简化:在一个位置捕获多个异常。

在这里。

try{
    try{
        trans.commit();
    } catch (HeuristicMixedException e) {
        if(log.isErrorEnabled()){
            log.error(e);
        }
        trans.rollback(); //catch SystemException at another level
        //Note: We are now leaving this catch block as if
        //  the program state is okay again.
    } catch (RollbackException|HeuristicRollbackException e){
        if(log.isErrorEnabled()){
            log.error(e);
        }
        //don't need to rollback

        //Note: We are now leaving this catch block as if
        //  the program state is okay again.
    }
    //let SystemException propagate
}catch(SystemException e){
    //!do something
    //fix it or rethrow
}