【问题标题】:Implementing Audit Trail- Spring AOP vs.Hibernate Interceptor vs DB Trigger实施审计追踪——Spring AOP vs.Hibernate Interceptor vs DB Trigger
【发布时间】:2010-10-20 14:58:56
【问题描述】:

我在这方面找到了几个讨论线程 - 但没有任何内容可以在一个线程下对所有三种机制进行比较。

所以这是我的问题...

我需要审核数据库更改 - 插入\更新\删除到业务对象。

我能想到三种方法来做到这一点

1) 数据库触发器

2) 休眠拦截器

3) Spring AOP

(这个问题特定于 Spring\Hibernate\RDBMS - 我想这对 java\c# 或 hibernate\nhibernate 是中性的 - 但如果您的答案取决于 C++ 或 Java 或 hibernate 的特定实现 - 请指定)

选择其中一种策略的优缺点是什么?

我不是在询问实现细节。-这是一个设计讨论。

我希望我们可以将其作为社区 wiki 的一部分

【问题讨论】:

  • 还有另一种选择:至少有些数据库具有相同的审计功能。 Pro:非常依赖,可能是高性能;缺点:高度特定于供应商

标签: database hibernate audit spring-aop


【解决方案1】:

我只能讲Triggers和NHibernate,因为我对Spring AOP了解不够。

与往常一样,这取决于对您来说最重要的是什么。

数据库触发器

  • 速度很快
  • 总是被调用,即使是从本机 SQL、脚本、外部应用程序。
  • 在 NH 不知道的 DB 中写入数据。它将在当前会话中丢失。 (这可能会导致意想不到的结果)
  • 通常对您的会话一无所知(例如:登录名)。

NHibernate 拦截器/事件

  • 不是 DBMS 特定的。
  • 让您可以轻松访问您的业务信息,例如用户会话、客户端计算机名称、某些计算或解释、本地化等。
  • 允许您进行声明性配置,例如实体上的属性,这些属性定义是否需要记录实体以及如何记录。
  • 允许您关闭日志记录,这对于升级、导入、非用户触发的特殊操作可能很重要。
  • 允许您查看业务模型的实体视图。您可能更接近用户的观点。

【讨论】:

  • 我们可以记录使用数据库触发器更改数据的用户名吗?
  • 我怎么知道?如果您知道数据库中的用户,您只能执行此操作。通常,您将用户会话保存在服务器的内存中,而数据库不知道它。
【解决方案2】:

我知道这与问题不是 100% 相关,但它确实通过新选项增加了价值。

您可以通过另外两种方式来审核正在发生的事情。

读取事务日志:如果数据库处于完全恢复模式,则有关 INSERT、UPDATE、DELETE 和 DDL 语句的所有详细信息都会记录到事务日志中。

问题在于它读取起来非常复杂,因为它本身不支持,并且您需要第三方事务日志读取器,例如 ApexSQL LogSQL Log Rescue(后者是免费的,但仅支持 sql 2000)。

这种方法的优点是,除了将数据库置于完全恢复模式之外,您实际上不需要进行任何更改。

SQL Server 跟踪:跟踪将捕获跟踪文件中的所有内容,包括某些合规性方案可能需要的选择语句。缺点是跟踪是需要解析和组织的文本文件。

【讨论】:

    【解决方案3】:

    我想不出任何不使用数据库触发器来审核数据库更改的充分理由。插入、更新和删除可能会从各种来源命中数据库——触发器会捕获所有这些;休眠等不会。

    【讨论】:

    • 我支持你,确保对数据库上的所有活动进行审计的唯一方法是在数据库级别进行。
    • 如果你想切换数据库怎么办?重写所有触发器?
    • @Icarus:如果您切换数据库,那将是您需要做的许多事情之一,是的。实际上,企业并不倾向于切换数据库。
    • 数据库触发器知道的关于上下文的唯一信息是日期和数据库登录名。当您有一个应用程序通过单个登录连接时,只留下日期(和数据更改)。只有日期的价值取决于您正在进行的审计类型。
    【解决方案4】:

    我认为当您考虑审计时,您需要考虑它的用途。首先,它是记录谁更改了什么以及更改了什么,这样您就可以撤消错误的更改,您可以识别系统的问题(我们可以看到几个不同的应用程序中的哪个导致了更改,这有助于快速识别哪个应用程序损坏了)这样您就可以确定是谁进行了更改。在检测欺诈方面,最后一个可能非常关键。如果您从用户界面做所有事情,您将永远不会看到用户进行欺诈,他们更改后端的数据以给自己写一张支票。如果您从界面执行所有操作,则可能必须在表级别设置权限,从而为欺诈打开大门。如果您从界面执行所有操作,您将不知道哪个心怀不满的员工删除了整个用户表以获得纯粹的烦恼值。如果您从前端做所有事情,您将不知道哪个不称职的 dba 不小心将所有客户订单更新到同一客户。我不支持使用除了触发器之外的任何东西进行审计,因为你首先失去了为什么需要审计的很大一部分。

    【讨论】:

      【解决方案5】:

      使用 Hibernate 拦截器执行审计日志存在严重缺陷。我对推荐这种方法的博客数量感到震惊,但没有指出它最明显的缺陷——拦截器必须使用新事务来记录审计。这意味着您可以成功保存主交易,但系统崩溃无法记录审计交易!

      【讨论】:

      • 您当然不希望日志事务崩溃导致主事务失败。
      • 我想你会的。因为如果没有,那么从审核员的角度来看,您的审核日志不再是系统中实际发生或未发生的事情的可靠“真相”。仅供参考:我们实现了一个系统,我们使用 Javassist 包装休眠实体以捕获 settter 方法调用和更改(对于集合来说稍微复杂一些)并将其存储在附加到事务的“作业”中(我们的休眠层允许这样做)并很好地捕获审计更改。
      【解决方案6】:

      我现在偶然发现的一个老问题。还有一个可用的选项,那就是 Envers,它从 3.6 版开始与休眠一起可用..

      【讨论】:

        猜你喜欢
        • 2012-02-13
        • 2011-05-12
        • 1970-01-01
        • 2011-08-27
        • 2021-05-21
        • 1970-01-01
        • 2012-10-27
        • 1970-01-01
        • 2010-11-07
        相关资源
        最近更新 更多