【问题标题】:How to catch OptimisticLockException in servlet level?如何在 servlet 级别捕获 OptimisticLockException?
【发布时间】:2011-08-23 01:44:44
【问题描述】:

我正在使用 JPA toplink-essential,构建 REST Web 应用程序。

我有一个 servlet 可以找到一个实体并将其删除。

下面的代码我认为我可以在 servlet 级别捕获乐观锁异常,但事实并非如此! 而是抛出 RollbackException,这就是文档所说的:

但是当我在某个地方看到 Netbean IDE GlassFish 日志时,会抛出optimisticLockException。它只是没有被我的代码捕获。 (我的系统打印消息没有显示,所以我确定它不会出现在那里。)

我尝试导入每个包(当然一次一个)并使用 catch 子句进行测试,但两次都没有进入 catch 块,即使日志错误显示“乐观异常”。

import javax.persistence.OptimisticLockException;
import oracle.toplink.essentials.exceptions.OptimisticLockException;

那么 OptimisticLockException 是在哪里抛出的??????

@Path("delete")
@DELETE
@Consumes("application/json")
public Object planDelete(String content) {

   try {
            EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager();

            EntityTransaction txn = em.getTransaction();
            txn.begin();
            jObj = new JSONObject(content);
            MyBeany bean = em.find(123);

            bean.setVersion(Integer.parseInt(12345));
            em.remove(bean);


            //here commit!!!!!
            em.getTransaction().commit(); 
        }
        catch(OptimisticLockException e) {  //this is not caught here :(
            System.out.pritnln("here");
            //EntityTransactionManager.rollback(txn);
            return HttpStatusHandler.sendConflict();
        }
        catch(RollbackException e) {
            return HttpStatusHandler.sendConflict();
        }
        catch(Exception e) {
            return HttpStatusHandler.sendServerError(e);
        }
        finally {
            if(em != null) {
                em.close();
            }
        }

错误信息:

[TopLink Warning]: 2011.01.28 05:11:24.007--UnitOfWork(22566987)
--Exception [TOPLINK-5006] 
(Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): 
oracle.toplink.essentials.exceptions.OptimisticLockException

    [TopLink Warning]: 2011.02.01 08:50:15.095--UnitOfWork(681660)--
javax.persistence.OptimisticLockException: Exception [TOPLINK-5006] (Oracle TopLink 
Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): 
oracle.toplink.essentials.exceptions.OptimisticLockException

【问题讨论】:

    标签: java jpa toplink-essentials


    【解决方案1】:

    不是 100% 肯定,但可能是您正在捕获 javax.persistence.OptimisticLockException(注意包),但由于抛出的异常是 oracle.toplink.essentials.exceptions.OptimisticLockException,它没有被捕获吗?尽管异常类的名称相同,但它们不是同一个类。

    【讨论】:

    • 好点。我在上面的代码中捕获了 javax.persistence.OptimisticLockException。我改变了我的 catch 子句来捕捉 oracle.toplink.essentials.exceptions.OptimisticLockException 但它直到没有捕捉到。我在帖子中添加了错误消息。它显示了两种类型的包.. 非常混乱
    • 所以我的猜测正如 Ralph 指出的那样,异常是在 em.getTransaction().commit 内部引发的,所以我无法手动捕获optimisticLockException。唯一的方法是捕获回滚异常并假设发生“冲突”??? :(
    • “catch(Exception e)”应该捕获在 try 块中抛出的任何异常(未经检查或检查)。您可能应该从该异常中获取堆栈跟踪和/或在提交行设置断点并单步执行代码以查看发生了什么。
    • 经过研究和几次测试,在我的情况下似乎无法捕捉到它。虽然区分的一种方法是何时抛出 RollbackException,e.getCause() 然后查看它是否是optimisticLockException。就我而言,这足以满足我的需要:)
    【解决方案2】:

    我猜它是在em.getTransaction().commit(); 语句中抛出的。

    因为java doc of RollbackException 如果说:

    当 EntityTransaction.commit() 失败时由持久化提供者抛出。

    我坚信这不是您在bean.setVersion(Integer.parseInt(12345); 行中真正使用的代码(由于缺少 ,因此无法编译),但我“希望”真正的代码有同样的问题。

    【讨论】:

    • 我修正了那个错字,但问题仍然是两个乐观锁包都没有被捕获。
    【解决方案3】:

    您是否尝试过调用 entityManager.flush();在你的 try/catch 块内? JPA 刷新是抛出 OptimisticLock 异常的时间。

    此外,您不需要以您所做的方式提交事务。你可以简单地完成 txn.commit();而不是 em.getTransaction().commit();.

    我有类似的情况,我能够捕获 javax.persistence.OptimisticLockException。就我而言,我将 ReST 端点设为 SSB 并注入实体管理器。然后我在另一个 SSB 上调用一个方法,该方法也被注入并充当这个 biz 逻辑的控制器。此控制器执行 flush() 并捕获 OLEX 并重新抛出 Rest 端点/SSB 捕获并重试的 ApplicationException。使用此模式,您还需要确保指定 TransactionAttributeType.RequiresNew,以便您进行的每次重试都发生在新事务中,因为 OLEX 会使旧事务无效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      相关资源
      最近更新 更多