数据库异常处理最佳实践

时间:2008-09-02 12:25:35

标签: database exception architecture

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

以下是一些方法:

  1. 在将数据传递给DB之前验证数据
  2. 对DB进行验证并正确处理数据库异常
  3. 双方验证
  4. 验证业务逻辑中的一些明显约束,并将复杂验证留给DB
  5. 您使用什么方法?为什么呢?

    更新:

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

    建议:

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

7 个答案:

答案 0 :(得分:6)

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

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

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

正在进行一些尝试来统一交叉责任,例如P& P组Policy Injection Application Block与其Validation Application Block相结合的政策注射器中的验证,但这些仍然是基于代码的。如果您的验证不在代码中,则仍需要单独维护并行逻辑...

答案 1 :(得分:4)

在客户端和数据库端进行验证有一个杀手锏,即安全性。特别是当你开始使用AJAX-stuff,黑客URL和其他使你的网站(在这种情况下)对用户黑客更友好的东西时。

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

答案 2 :(得分:3)

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

但是,有些数据错误无法以编程方式检查。例如,如果不向数据包进行往返,则无法验证相关数据存在的数据。像这样的数据错误应该由数据库通过使用关系,触发器等来验证。

处理数据库调用返回的错误的地方很有意思。您可以在数据层,业务逻辑层或UI层处理它们。在这种情况下,最好的做法是让这些错误在处理之前冒泡到最后的责任时刻。

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

TL; DR:在任何地方验证,在最后一个负责任的时刻处理验证错误。

答案 3 :(得分:2)

我尝试双方验证。我始终遵循的1条规则绝不是用户的信任输入。根据它的结论,我通常会在表单/网页上进行一些前端验证,甚至不允许提交不正确的数据。这是一个生硬的工具 - 这意味着您可以检查/解析该值以确保日期字段包含日期。从那里开始,我通常会让我的业务逻辑检查数据条目是否与提交方式有关。例如,提交的日期是否属于预期范围?提交的货币价值是否属于预期范围?最后,在服务器端,外键约束和索引可以捕获任何漏掉的错误,这将作为最后的手段冒出数据库异常,可以由应用程序代码处理。我使用此方法是因为它在调用DB调用之前过滤掉尽可能多的错误。

答案 4 :(得分:2)

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

答案 5 :(得分:1)

一般情况下,我尝试在输入数据后尽快验证数据。这样我就可以在用户点击“提交”或等效内容之前提前向用户发送有用的信息 在进行数据库调用时,我希望我传递的数据应该相当不错 我尝试将db调用保存在共享帮助器方法的一个文件(或文件组)中,使程序员(我或其他任何添加调用的人)尽可能简单地写入有关异常的日志详细信息,以及哪些参数被传递等

答案 6 :(得分:0)

我写的各种应用程序(我已经移动了工作)是内部胖客户端应用程序。
我会尝试将业务逻辑保留在客户端,并对数据库进行更多的机械验证(即验证只与程序的运行能力相关,而不是更高级别的验证)。
简而言之,验证您可以在哪里,并尝试将相关类型的验证保持在一起。