【问题标题】:How to build a change tracking system - not audit system如何建立变更跟踪系统——而不是审计系统
【发布时间】:2011-03-30 13:03:13
【问题描述】:

我有一个需求,我需要在库存中捕获数据更改(不是审计)和生命周期状态。

技术: Jave、Oracle、Hibernate + JPA

对于数据更改,我们获得了要监控的数据元素列表。如果元素发生变化,我们将通知给定的第 3 方供应商。我想要做的是让这个通用服务成为我们可以提供给我们当前和未来的任何第 3 方供应商的服务。

我们不在乎是谁进行了更改,也不在乎新值是什么。

我们的想法是我们应用程序的数据层将在每个数据元素上使用注释。如果该数据元素发生了变化,那么它会将消息放入队列中。然后消息 bean 将读取队列并在表中创建一个条目。

表格如下所示:


Table Name: ATL_CHANGE_TRACKER  
Key  columns  
INVENTORY_ID          Inventory Id of the vehicle
SALEEVENT_ITEM_ID     SaleEvent item of the vehicle
FIELD_CHANGED_ID      Id of the field that got changed or action. Link to subscription
UPDATE_DTM            Indicates the date time when change occured.

对于给定的库存,我们在此表中最多可以有 200 个条目(监控多个表中的 200 个字段)。

然后,给定第 3 方的守护程序将根据它已订阅的字段(可能是所有字段)从该表中读取。然后它将读取创建要发送给第三方的消息所需的每个表。解耦数据的提供者和数据的使用者。

确定可用字段/操作的列表


Table Name: ATL_FIELD_ACTION  
Key columns  
ID  
NAME                    Name of the field/action - Example Color,Make
REC_CRE_TIME_STAMP  
REC_CRE_USER_ID  
LAST_UPDATE_USER_ID  
LAST_UPDATE_TIME_STAMP  

订阅表,如果第 3 方公司 xyz 对 60 个字段感兴趣,这 60 个字段将映射到此表。


ATL_FIELD_ACTION_SUBSCRIPTION  
Key columns  
ATL_FIELD_ACTION_ ID      ID of the atl_field_action table
CONSUMER                  3rd Party Name
FUNCTION                  Name of the 3rd Party Transmission that it is used for
STATUS  
REC_CRE_TIME_STAMP  
REC_CRE_USER_ID  
LAST_UPDATE_USER_ID  
LAST_UPDATE_TIME_STAMP  

第二部分是对库存生命周期的一些操作,这些操作也需要记录。在这种情况下,当库存状态发生变化时,一条消息将被放置在同一个队列中,并且该条目将被输入到同一个表中。

同样,守护进程将订阅这些状态并收集它感兴趣的状态。

这里的目标是不让需要数据的业务层/数据层关心 - 只是它需要提供数据,以便感兴趣的人可以获得它。

想知道是否有人做过这样的事情——任何陷阱——现成的——开源解决方案。

【问题讨论】:

  • 也许 DBMS_ALERT 包会有所帮助
  • 你有没有决定过你喜欢的方法?我正在处理一个类似的场景,并没有看到很多关于这个主题的文章。

标签: java oracle hibernate jpa


【解决方案1】:

有关该主题的高级讨论,我建议阅读 Martin Fowler 的 this article

听起来你有一次写入,多次读取的数据类型,它可能会产生大量数据,并且不同客户端的数据不同。如果您问我,这听起来可能是一个使用 NOSQL 数据库或破解您的 Oracle 数据库以充当 NOSQL 数据库的好地方。请参阅here,了解有关有人如何使用 MySQL 进行此操作的讨论。

否则,您可能会考虑创建一个“不可变”数据库表,并让 Hibernate 在每次更新时写入新记录,如 here 所述。

【讨论】:

    【解决方案2】:

    几件事。

    首先,您可以自己完成所有这些工作。 JPA/Hibernate 生命周期侦听器,虽然它们有一个更新发生时的事件,但不会传递“旧”对象和“新”对象。因此,您将不得不使用其他方法跟踪哪些字段发生了变化。

    其次,再次使用生命周期侦听器,在它们内部要小心,因为事务状态有点模糊。至少在 Glassfish/EclipseLink 上,我在使用来自生命周期侦听器的 JPA 或 JMS 时遇到了“奇怪”的问题。只是奇怪的行为。我们进入一个非事务队列来捕获我们从生命周期事件中跟踪的所有信息。

    如果在自己的事务中提交更改数据是可以接受的,那么将数据推送到更快的内部队列(可以提供将其发布到 MDB 的侦听器)是有价值的。这只是让您的交易“带外”审计,为您提供更好的交易吞吐量。但是,如果您需要在同一个事务中提交更改信息,这将不起作用。例如,您可以将某些内容放在队列中,然后事务可能会回滚(无论出于何种原因),使队列上的更改显示它发生了,而实际上它失败了。这是一个潜在的问题。

    但如果您要发布大量审计信息,那么这可能是一个问题。

    如果审计信息的生命周期很短(相对于其余数据),那么您可能应该努力剔除审计表,它们可能会变得非常大。

    此外,如果可行,请不要忽视为此使用数据库触发器。在这个过程中,他们可以非常高效和有效。

    【讨论】:

    • “我在使用来自生命周期侦听器的 JPA 或 JMS 时遇到了“奇怪的”问题。”你的意思是把 EntityManager 注入你的审计层是麻烦的根源吗?如果您决定不在生命周期侦听器中使用 JPA,您是如何确定新旧实体之间的差异的?
    猜你喜欢
    • 2011-04-20
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 2011-02-10
    • 2012-04-03
    • 2019-01-04
    相关资源
    最近更新 更多