什么是在Java中完成事务的正确代码模式(异常回滚和成功提交)?

前端之家收集整理的这篇文章主要介绍了什么是在Java中完成事务的正确代码模式(异常回滚和成功提交)?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在寻找通用代码模式来正确处理可能异常的事务.我假设有一个共同的代码模式,无论我们处理什么样的交易.

我有一个方法在事务中执行某些事情,并希望重新抛出在事务代码块内部可能发生的异常.以下是此类方法的示例:

protected void doIt() {
  // for JDBC connection transaction may be started automatically
  // but assume we start it here
  Tran tran = session.beginTran();
  try {
    // here comes code that does some processing
    // modifies some data in transaction
    // etc.

    // success - so commit
    tran.commit();

  } catch (Exception ex) { // many different exceptions may be thrown
                           // subclass of RuntimeException,sqlException etc.
     // error - so rollback
     tran.rollback();

     // now rethrow ex
     throw ex;              // this line causes trouble,see description below
  }      
}

现在 – 方法doIt中存在编译错误.它必须声明throws Exception但这是不可接受的,因为方法doIt在很多地方使用并添加throws Exception导致在直接和间接使用doIt的地方进行后续修改.这是因为已知的Java语言设计问题与声明的异常.

现在的问题是:如何更改异常与事务处理代码以实现我的目标 – 正确处理事务完成(基于成功条件执行提交或回滚)并重新抛出可能在事务代码块中捕获的完全相同的异常.

我知道我可以做一些像抛出新的RuntimeException(ex)但这会抛出其他类的异常,我想避免这样的解决方案.

解决方法

我会选择这样的东西.
protected void doIt() {
  // for JDBC connection transaction may be started automatically
  // but assume we start it here
  Tran tran = session.beginTran();
  bool success = false;
  try {
    // here comes code that does some processing
    // modifies some data in transaction
    // etc.

    // success - so commit
    tran.commit();
    success = true;
  } finally { 
     // error - so rollback
     if (! success)
       tran.rollback();
  }      
}

..或者如果tran有一个方法可以查询状态(tran.isFinished())或其他东西,你不需要bool.任何抛出的异常(即运行时异常或错误,如果没有已检查的异常)都会直接执行,在堆栈上执行finally块.

如果rollback抛出异常,你将需要捕获那些和log-em或其他东西(失败的回滚是一个非常严重的情况).记住在这种情况下不要抛出任何东西,因为当前展开堆栈的异常将丢失.

原文链接:https://www.f2er.com/java/120795.html

猜你在找的Java相关文章