gpt4 book ai didi

java - 为什么抛出EJBException是 "recommended"的做法?

转载 作者:搜寻专家 更新时间:2023-10-30 21:30:17 27 4
gpt4 key购买 nike

我不断地从许多开发人员那里得到这个“建议”。根据我的经验,我发现 EJBExceptions 非常适合从 bean 实例的角度来看的“世界末日”(比如当出现错误以至于 bean 实例无法自行恢复时)。如果一个实例可以恢复,我认为抛出一个应用程序异常会更好。

这是我一次又一次遇到的模式:

private SomeResource resource;ejbCreate:    resource = allocateResource(...);omMessage:    try {    ...    } catch (JMSException e) {        throw new EJBException(e);    }ejbRemove:    freeResource(resource);

恕我直言,这是一种导致资源泄漏的反模式。

编辑:具体来说,EJB 规范指出,如果一个 bean 从业务方法中抛出一个运行时异常(EJBException 是一个运行时异常),那么该 bean 将被丢弃,而不对其调用 ejbRemove。

这是反对抛出 EJBException 的相关示例吗?应该抛出 EJBException 的相关情况有哪些?

最佳答案

EJB 规范(EJB 3 中的 14.2.2)推荐在 EJB 无法从它遇到的异常中恢复的情况下抛出 EJBException。该规范还指出,EJB 可以合理地允许(未经检查的)系统异常传播到容器。

我同意您阅读规范,在这种情况下容器不会调用生命周期回调方法,因此您担心通常会在 ejbRemove() 中发生的任何资源整理 不会发生回调,因此存在资源泄漏的危险。

我的经验是,由于缺乏防御性编码,会出现很多棘手的问题。 “情况 X 不可能发生在一个表现良好的系统中,如果它发生了,那么整个系统就会崩溃,所以我不会为这种可能性编写代码。”然后我们得到了一些“有趣”的星星对齐和运算符(operator)错误,并且“不可能发生”快速连续发生多次,意想不到的副作用开始导致真正难以诊断的问题。

因此我会说:

  1. 尽你所能使 Bean 实例处于下一次调用业务方法可能起作用的状态。这可能意味着捕获异常并关闭出错的资源。在这种情况下,您可能会选择告诉调用者,“抱歉,老大,该请求无效,但如果您稍后重试……”我通过抛出一个 TransientException 检查异常来做到这一点。
  2. 如果您在 ejbRemove 中没有重要的内务处理,那么您可以允许 SystemExceptions 传播 - 但我不确定这是否友好。您依赖于一个库,它会抛出一个 NullPointerException。捕获并重新抛出 TransientException 实际上更可靠吗?
  3. 如果您确实有重要的内务管理工作,那么我认为您确实需要捕获所有异常并至少尝试进行清理。然后您可以选择重新抛出 EJBException 或系统异常,以便销毁该实例,但至少您已尝试进行内务处理。

关于java - 为什么抛出EJBException是 "recommended"的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1581600/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com