数据库异常处理最佳实践

15
我该如何处理应用程序中的数据库异常? 您是在将数据传递到DB之前验证数据还是仅依赖于DB模式验证逻辑? 您是否尝试从某些类型的DB错误(例如超时)中恢复?
以下是一些方法:
1. 在将数据传递到DB之前验证数据 2. 将验证留给DB并正确处理DB异常 3. 在两端进行验证 4. 在业务逻辑中验证一些明显的约束,并将复杂的验证留给DB
您使用哪种方法?为什么?
更新:
我很高兴看到越来越多的讨论。 让我们尝试总结社区答案。
建议:

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

7个回答

7

@aku: DRY很好,但并非总是可行的。验证就是其中之一,在这里你会有三个完全不同和无关的地方需要进行验证:在UI内,在业务逻辑内和在数据库内都不仅可能而且绝对需要。

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

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

目前有一些尝试将跨越验证等横切责任统一到策略注入器中,例如P&P组的Policy Injection Application Block结合他们的Validation Application Block,但这些仍然是基于代码的。如果您有不在代码中的验证,您仍然必须单独维护并行逻辑...


5

在客户端和数据库端都进行验证的一个致命原因是安全性。特别是当你开始使用AJAX、易受攻击的URL和其他使你的网站(在这种情况下)更加用户友好和黑客友好的东西时。

在客户端进行验证可以提供平滑的体验,及早告诉用户纠正他们的输入。同时,在数据库中进行验证(或在业务逻辑中进行验证,如果这被认为是一个完全安全的数据库网关),以保证你的数据库的安全。


3
您希望减少对数据库的不必要访问,因此在应用程序中进行验证是一个好的做法。此外,它允许您处理数据错误,最容易从中恢复的地方:接近UI(无论是在控制器中还是在较简单应用程序的UI层中)输入数据的位置。
然而,有些数据错误是无法通过编程方式检查的。例如,您无法验证相关数据的存在性而不经过往返数据库。这样的数据错误应该通过使用关系、触发器等由数据库进行验证。
在哪里处理数据库调用返回的错误是一个有趣的问题。您可以在数据层、业务逻辑层或UI层处理它们。在这种情况下,最佳实践是让这些错误在处理之前上升到最后一个负责的时刻。
例如,如果您有一个ASP.NET MVC Web应用程序,您有三个层次(从底部到顶部):数据库、控制器和UI(模型、控制器和视图)。您的数据层抛出的任何错误都应该被允许上升到控制器。在这个级别上,您的应用程序“知道”用户正在尝试做什么,并且可以正确地通知用户有关错误的信息,建议不同的处理方式。在数据层内尝试从这些错误中恢复会使得在控制器内部难以知道发生了什么。当然,在UI中放置业务逻辑不被认为是最佳实践。
简而言之,到处验证,在最后一个负责的时刻处理验证错误。

2

我尝试在两个方面进行验证。我一直遵循的一个规则是不要相信用户输入的内容。为了贯彻这一点,我通常在表单/网页上进行前端验证,如果数据格式不正确,甚至不允许提交。这是一个粗暴的工具 - 意味着您可以检查/解析值,以确保日期字段包含日期。从那里开始,我通常让我的业务逻辑检查数据录入是否符合提交方式的上下文意义。例如,提交的日期是否落在预期范围内?提交的货币价值是否落在预期范围内?最后,在服务器端,外键约束和索引可以捕获任何滑过的错误,作为最后的手段,会将数据库异常波动到应用程序代码中来处理。我使用这种方法是因为它能在调用DB之前过滤掉尽可能多的错误。


2
一个对象关系映射(ORM)工具,比如NHibernate(或者更好的ActiveRecord),可以帮助你避免很多验证问题,因为它允许数据模型被构建成一个合适的 C# 类并直接嵌入到你的代码中。由于框架内置了优秀的缓存和验证模型,你也可以避免频繁访问数据库。

1
一般来说,我会尽快验证数据是否正确输入。这样做是为了在用户点击“提交”或等效操作之前尽早提供有用的信息。
到进行数据库调用时,我希望传递的数据应该是相当好的。
我尝试将数据库调用保留在一个文件(或一组文件)中,共享辅助方法,使程序员(我或其他添加调用的人)能够尽可能轻松地编写关于异常的日志详细信息以及传递的参数等。

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

@hamishmcn。说得好,业务逻辑层中设置验证规则的一大原因是为了创建用户友好的用户界面。但是在多个地方设置这些验证规则违反了DRY原则。你如何解决在数据库和客户端验证之间保持同步的问题? - aku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接