数据库异常处理最佳实践

数据库异常处理最佳实践

Database exception handling best practices

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

以下是一些方法:

  • 验证数据,然后再将其传递给数据库
  • 将验证留给数据库并正确处理数据库异常
  • 双方验证
  • 验证业务逻辑中的一些明显限制,并将复杂的验证留给数据库
  • 您使用什么方法?为什么?

    更新:

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

    意见建议:

    • 双方验证
    • 检查以下方面的业务逻辑约束
      客户端,让DB从hamishmcn进行完整性检查
    • 尽早检查以免困扰ajmastrean
    • 尽早检查以改善Will的用户体验
    • 保持数据库交互代码到位
      简化hamishmcn的开发
    • 对象关系映射(NHibernate,Linq等)可以帮助您处理来自ajmastrean的约束
    • 出于安全原因,Seb Nilsson必须进行客户端验证

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


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

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

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

    已经进行了一些尝试来统一跨部门的职责,例如在策略注入程序中进行验证,例如P&P组的策略注入应用程序块及其验证应用程序块,但是这些仍然基于代码。如果您的验证不在代码中,则仍然必须分别维护并行逻辑...


    在客户端和数据库侧都需要进行验证的一个致命原因,那就是安全性。特别是当您开始使用AJAX素材,可入侵的URL和其他使您的网站(在这种情况下)对用户和黑客更友好的东西时。

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


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

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

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

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

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


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


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


    通常,我尝试在输入数据后尽快验证数据。这样一来,我可以在用户单击"提交"或等效按钮之前,向他们提供有用的消息。
    我希望在进行数据库调用时,我传递的数据应该相当不错。
    我尝试将数据库调用保留在共享帮助程序方法的一个文件(或一组文件)中,以使程序员(我或其他添加调用的人)尽可能容易地将有关异常以及什么参数的日志详细信息写入日志通过了等等


    我正在编写的应用程序(自从转职以来)是内部胖客户端应用程序。
    我将尝试将业务逻辑保留在客户端中,并在数据库上进行更多的机械验证(即,仅与过程的运行能力相关的验证,而不是更高级别的验证)。
    简而言之,请在可能的地方进行验证,并尝试将相关的验证类型放在一起。


    推荐阅读