【发布时间】:2011-08-22 07:17:32
【问题描述】:
请求流-Jsf(Backing Bean)->业务层->DAO层(spring Dao)
一些文章建议 DAO 层捕获所有 sql 异常并应抛出已检查异常。业务层捕获该异常并根据业务规则抛出自定义异常。
我的疑问是 spring hibernateTemplate 已经将所有异常转换为未检查的异常,为什么我应该从 DAO 抛出已检查的异常?
请提出一些好的方法。谢谢
【问题讨论】:
请求流-Jsf(Backing Bean)->业务层->DAO层(spring Dao)
一些文章建议 DAO 层捕获所有 sql 异常并应抛出已检查异常。业务层捕获该异常并根据业务规则抛出自定义异常。
我的疑问是 spring hibernateTemplate 已经将所有异常转换为未检查的异常,为什么我应该从 DAO 抛出已检查的异常?
请提出一些好的方法。谢谢
【问题讨论】:
我的疑问是 spring hibernateTemplate 已经转换了所有异常 进入未经检查的异常为什么我应该从 道?
A) hibernateTemplate 将特定于基础设施的检查异常转换为 RuntimeExceptions。这很好,您的服务层不应该处理特定于技术的异常。您可能想要抛出的已检查异常将属于您自己的层次结构,其名称和抽象对于在平台内跨层传达故障是有意义的。
b) HibernateTemplate(以及 JpaTemplate,就此而言)不再是推荐的做事方式。从 Spring 3 开始,应使用纯 Hibernate(或纯 JPA),事务管理和异常转换应仅通过 AOP 进行。
【讨论】:
在我看来,有两种类型的异常:
由于违反业务规则(例如,如果用户尝试创建已存在的记录,或者用户尝试提取的资金多于其帐户中的资金)会导致预期的异常。
意外的异常是由不可预见的情况引起的(例如,您的数据库崩溃、代码中的错误或无法访问远程服务器)。
应该优雅地处理预期的异常(例如,应该很好地告诉用户他需要做一些不同的事情(例如尝试用更少的钱取款),或者应用程序应该执行一些纠正措施。
在这种情况下,我认为检查异常很有意义,因为它可以确保特定服务的消费者处理异常。
在您无法从异常中恢复的情况下(例如,如果数据库已关闭,或者 SQL 查询格式错误),那么您只能记录异常并显示通用的“某事发生了可怕的错误,请告诉系统管理员”消息给用户。在这种情况下,异常应该保持未经检查,在最高级别捕获并写入日志,以后可以分析该日志以确定是否需要修复错误或向数据库添加更多弹性(备份、故障转移等)
因此,例如,如果您有一个使用 HibernateTemplate 的 DAO,当违反主键时会抛出 DataIntegrityViolationException,那么捕获它并将其转换为业务异常是有意义的。但是,将DataAccessException 的所有实例转换为业务异常是没有意义的,因为您将无法执行任何操作,例如使用BadSqlGrammarException 或告诉您特定表不存在的异常。
希望对您有所帮助。
【讨论】:
忽略“一些文章”。 -- 有时一个框架不支持你想要的架构。在这种情况下,您有两种选择
如果你的规则没有充分的理由,那么第二种方式主要是禁食。
顺便说一句:我想有人会在“一些文章”中找到相同数量的反对意见。 (根本不要使用受检异常)
我的个人建议是对业务相关的规则内容使用已检查的 ecception,而对于所有无法处理的技术问题(例如丢失的数据库连接)不进行检查。
【讨论】: