哪个是处理异常的最佳位置?BLL、DAL 还是 PL?

我是否应该允许 DAL 和 BLL 中的方法将异常抛出链并让 PL 处理它们?或者我应该在 BLL 处理它们?

例如

如果我的 DAL 中有一种方法发出“ExecuteNonQuery”并更新一些记录,并且由于一个或多个原因,0 行受到影响。现在,我应该如何让我的 PL 知道是否发生了异常或者确实没有与条件匹配的行。我应该在我的 PL 代码中使用“try catch”并通过异常让它知道,还是应该在 DAL 处处理异常并返回一些特殊代码,例如 (-1) 以让 PL 区分 (异常) 和 (no行匹配条件,即受影响的零行)?

有帮助吗?

解决方案

这是没有意义让那在DAL气泡直至PL引发的异常 - 如何是应该反应如果数据库连接不能建立用户

捕获并处理异常早,如果您可以处理它们。不要只吞下他们没有输出提示或日志信息 - 这会导致一些难以跟踪严重的困难和错误

其他提示

这是一个很大的话题,有很多不必要的争议(大声说话的人会提供不好的信息!)如果你愿意处理这个问题,请遵循 s1mm0t 的建议,这基本上是令人愉快的。

然而,如果你想要一个词的答案, 将它们放入 PL 中。 严肃的。如果您可以逃脱它,请将您的错误处理放入全局异常处理程序中(所有错误都应记录并提供代码以出于安全原因在生产中查找日志(特别是如果是网络),但在开发期间返回完整的详细信息速度原因)。

编辑:(澄清) 你必须在任何地方处理一些错误 - 但这不是“每个功能”的规范。大多数时候让它们冒泡到 PL 并使用您自己的代码处理 .NET 的全局错误:通过一个通用例程从那里记录完整的调用堆栈,该例程可通过事件处理程序从所有 3 层访问(请参阅消息底部的编辑)。这意味着您将 不是 将 try/catch 贯穿于你的所有代码中;只是您期望的部分和错误,并且可以在那里处理它,或者非关键部分,您可以在其中记录错误并通知用户不可用的功能(这对于超级可靠/关键程序来说更加罕见)

除此之外,在处理资源有限的项目时,我经常使用“using”关键字或 try/finally/end try 而无需捕获。用于多线程锁/互斥锁/重入预防标志/等。在所有情况下,您还需要 try/finally ,以便您的程序仍然有效(尤其是有状态应用程序)。

如果您不正确地使用异常(例如,在应该使用 IF 语句或在尝试之前检查 iffy 操作是否有效时处理非错误),这种哲学将会更加崩溃。

旁注,在胖客户端应用程序中,特别是当有可能丢失大量数据或用户输入时,在尝试保存数据时进行更多尝试/捕获(当然标记为尚未有效)可能会更好)。

编辑: 另一个需要至少有 PL 中的日志记录例程 - 根据平台的不同,这会有所不同。我们正在开发的应用程序与 3 个 PL 版本共享 BLL/DAL:ASP.Net 版本、winforms 版本和控制台应用程序批处理模式回归测试版本。调用的日志例程实际上位于 BLL 中(DAL 仅抛出错误或完全处理它获取或重新抛出的任何错误)。然而,这会引发一个由 PL 处理的事件;在网络上,它将其放入服务器日志中,并显示网络风格的错误消息(对生产友好的消息);在 WinForms 中,会出现一个特殊的消息窗口,其中包含技术支持信息等。并在幕后记录错误(开发人员可以做一些“秘密”的事情来查看完整信息)。当然,在测试版本中,这是一个更简单的过程,但也有所不同。
除了传递参数“什么平台”之外,不知道如何在 BLL 中做到这一点,但由于它不包含日志记录所依赖的 winforms 或 asp 库,所以这仍然是一个技巧。

在简短的回答是这取决于!

您应该永远只处理异常,如果你可以用它做什么有用的。该“一些有用的东西”又取决于你在做什么。您可能需要记录异常的细节虽然这不是真正的处理,并在大多数情况下登录后你应该重新抛出异常。你可能想换一些其他(可能为自定义)异常异常,以了解更多信息添加到异常。作为上@mbeckish接触,你可能想尝试通过重试例如操作从异常恢复 - 你应该小心,不要永远但是重试。最后(原谅双关语),你可能要使用finally块来清理任何资源,如开放式数据库连接。你选择不同之处做会影响你在那里处理它。很可能是没有的,可以用比用户已发生错误在这种情况下将超过接受处理的UI层异常报告其他许多例外做有用的东西很大并且将问题报告给用户(你应该记录异常,以及,进一步下跌的层)。

当自己抛出异常,你应该永远只能抛出异常的“exceptional'circumstances,因为在抛出异常的一个很大的开销。在您的例子中,你认为你可能会想,如果没有记录您的操作更新抛出异常。这真的是特殊的?一个更好的东西在这种情况下,实在应该返回的记录数更新 - 这可能仍然是一个错误条件需要被报告给用户,但也不例外,如命令失败,因为connecction到DB有下降了。

是例外上合理的物品处理的最佳做法。

这是知道该怎么做,把事情的层正确的应该是该层处理异常。 例如,如果你决定通过重试查询一定次数来处理死锁错误,那么你可以建立一个到你的DAL。如果仍然失败,那么你可能想要让异常泡到下一层,然后可以决定是否知道如何妥善处理这一例外。

在您的应用程序的所有层应gracefullly管理例外。这是知道作为一个横切corncern,因为它出现在所有图层。 我相信,使用像企业异常块一个框架,统一,你会落得一个整体更好的代码。 这个帖子看看

http://msdn.microsoft。 COM / EN-US /库/ ff664698(v = PandP.50)的.aspx

这将需要某时掌握它,但也有很多的实施例和截屏围绕那里。

如何处理异常依赖于技术和业务需求。对于复杂的或者非常重要的数据库更新包括我的是通过已知错误的信息备份到DL的小单子PARAMS。这样一来,被错误场景可以通过编程方式在某些情况下得到解决。在其他情况下需要的错误进行记录,且必须通知用户错误的。

我使通知人类错误的实践。当然,记录将会给我们的详细信息,但它不能替代人的响应时间。不仅如此,但为什么迫使开发商看系统日志只是为了看看事情是南下?说说不必要的成本。

如果你有时间来确定潜在的错误/异常和程序解决这些问题,然后通过各种手段做到这一点。很多时候,错误/异常是意外。这就是为什么它重要的是要为意外准备什么更好的方式来做到这一点比涉及一个人。

总之,一个规划的异常处理时应该是在防守上。计划增长或他们死亡。生长的一部分是引入的错误。所以,不要让车轮空转试图杀死他们。

你的问题是其中的例外有关?如果它是一个数据访问异常,应该在DAL被抓住。如果它是一个逻辑异常,应该在BLL被抓住。如果它是一个呈现异常然后在PL。

举例来说,如果你的DAL抛出一个异常,它应该返回一个空或假或任何情况下可能是您的BLL。你应该BLL知道该怎么办,如果DAL返回一个空,也许它传递正确的通过,也许它会尝试调用另一个功能等也是一样与你的PL如果BLL通过从DAL或返回特定的东西空它自己的,则表示层应该能够通知最终用户,有一个问题。

当然,你将无法获得详细异常消息,但是这是一件好事,因为只要你的用户而言。你应该有一个灵活的日志系统捕获这些异常并将其报告给数据库或IP:端口或任何你决定。

从本质上讲,你需要考虑在的关注点分离的,如果关注的是数据问题或逻辑问题,应该进行相应的处理。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top