15

您如何处理应用程序中的数据库异常?
您是在将数据传递给 DB 之前尝试验证数据还是仅仅依赖 DB 模式验证逻辑?
您是否尝试从某种数据库错误(例如超时)中恢复?

以下是一些方法:

  1. 在将数据传递给数据库之前验证数据
  2. 将验证留给 DB 并正确处理 DB 异常
  3. 验证双方
  4. 验证业务逻辑中一些明显的约束,并将复杂的验证留给 DB

你用什么方法?为什么?

更新:

我很高兴看到越来越多的讨论。
让我们尝试总结社区的答案。

建议:

你还有什么要说的吗?这将转换为验证特定问题。我们缺少核心,即“与数据库相关的错误最佳实践”,哪些要处理,哪些要冒泡?

4

7 回答 7

6

@aku:DRY 很好,但并不总是可能的。验证就是其中之一,因为您将拥有三个完全不同且不相关的地方,验证不仅可能而且绝对需要:在 UI 内、业务逻辑内和数据库内。

想想一个 Web 应用程序。您希望减少对服务器的访问,因此您包括客户端数据输入的 javascript 验证。但是您不能相信用户输入的内容,因此您必须在接触数据库之前在业务逻辑中执行验证。并且数据库必须有自己的验证,以防止数据损坏。

没有一种简洁的方法可以将这三种不同类型的验证统一在一个组件中。

有一些尝试统一横切职责,如策略注入器中的验证,如 P&P 组的策略注入应用程序块与他们的验证应用程序块相结合,但这些仍然是基于代码的。如果您有不在代码中的验证,您仍然必须单独维护并行逻辑......

于 2008-09-02T13:06:00.343 回答
4

在客户端和数据库端都需要验证一个杀手锏,那就是安全性。尤其是当您开始使用 AJAX 材料、可破解 URL 和其他使您的网站(在这种情况下)对用户黑客更加友好的东西时。

在客户端上进行验证以提供流畅的体验,以便及早告诉用户更正他们的输入。还要在数据库中验证(或在业务逻辑中,如果这被认为是数据库的完全安全网关),以确保您的数据库安全。

于 2008-09-02T13:18:55.120 回答
3

您希望减少不必要的数据库访问,因此在应用程序中执行验证是一种很好的做法。此外,它还允许您在最容易恢复的地方处理数据错误:在输入数据的 UI 附近(无论是在控制器中还是在更简单的应用程序的 UI 层中)。

但是,您无法以编程方式检查某些数据错误。例如,如果不往返数据库,您将无法验证相关数据是否存在的数据。此类数据错误应由数据库通过使用关系、触发器等进行验证。

处理数据库调用返回的错误是一个有趣的问题。您可以在数据层、业务逻辑层或 UI 层处理它们。在这种情况下,最好的做法是让这些错误冒泡到最后一个负责任的时刻,然后再处理它们。

例如,如果您有一个 ASP.NET MVC Web 应用程序,您有三层(从下到上):数据库、控制器和 UI(模型、控制器和视图)。你的数据层抛出的任何错误都应该被允许冒泡到你的控制器中。在这个级别,您的应用程序“知道”用户正在尝试做什么,并且可以正确地通知用户有关错误,建议不同的方法来处理它。尝试从数据层中的这些错误中恢复会使了解控制器中发生的事情变得更加困难。当然,将业务逻辑放在 UI 中并不是最佳实践。

TL;DR:到处验证,在最后负责的时刻处理验证错误。

于 2008-09-02T12:54:23.993 回答
2

我尝试验证双方。我一直遵循的一条规则是永远不要相信用户的输入。在此得出结论后,我通常会在表单/网页上进行一些前端验证,甚至不允许提交格式不正确的数据。这是一个生硬的工具 - 这意味着您可以检查/解析该值以确保日期字段包含日期。从那里开始,我通常让我的业务逻辑检查数据条目在提交方式的上下文中是否有意义。例如,提交的日期是否在预期范围内?提交的币值是否在预期范围内?最后,在服务器端,外键约束和索引可以捕获任何漏掉的错误,这将作为最后的手段冒泡一个 DB 异常,这可以由应用程序代码处理。

于 2008-09-02T12:47:59.547 回答
2

对象关系映射 (ORM) 工具,例如NHibernate(或者更好的是ActiveRecord),可以通过允许将数据模型作为适当的 C# 类直接构建到您的代码中来帮助您避免大量验证。由于框架中内置了出色的缓存和验证模型,您也可以避免访问数据库。

于 2008-09-02T13:09:47.903 回答
1

一般来说,我会在输入数据后尽快验证数据。这样我就可以在用户单击“提交”或等效项之后更早地向用户提供有用的消息。
到进行 db 调用时,我希望我传递的数据应该相当好。
我尝试将 db 调用保留在共享辅助方法的一个文件(或一组文件)中,使程序员(我或其他添加调用的人)尽可能容易地写入有关异常的日志详细信息,以及哪些参数通过等

于 2008-09-02T12:44:47.667 回答
0

我正在编写的那种应用程序(我已经换了工作)是内部的胖客户端应用程序。
我会尝试将业务逻辑保留在客户端中,并在数据库上进行更多的机械验证(即仅与程序运行能力相关的验证,而不是更高级别的验证)。
简而言之,尽可能验证,并尝试将相关类型的验证放在一起。

于 2008-09-02T13:05:42.747 回答