Java 如何建立变更跟踪系统-而不是审计系统

Java 如何建立变更跟踪系统-而不是审计系统,java,oracle,hibernate,jpa,Java,Oracle,Hibernate,Jpa,我有一个需求,我需要捕获库存上的数据更改(而不是审计)和生命周期状态 技术: Jave、Oracle、Hibernate+JPA 对于数据更改,我们得到了要监视的数据元素列表。如果元件发生变化,我们将通知给定的第三方供应商。我想做的是使这成为一个通用的服务,我们可以提供给我们目前和未来的任何第三方供应商 我们不在乎是谁做出了改变,也不在乎新的价值是什么,只是它改变了 我们的想法是,应用程序的数据层将在每个数据元素上使用注释。如果该数据元素发生更改,那么它将把消息放入队列中。然后,消息bean将读

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

技术: Jave、Oracle、Hibernate+JPA

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

我们不在乎是谁做出了改变,也不在乎新的价值是什么,只是它改变了

我们的想法是,应用程序的数据层将在每个数据元素上使用注释。如果该数据元素发生更改,那么它将把消息放入队列中。然后,消息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个字段)

然后,给定第三方的守护进程将根据其订阅的字段(可能是所有字段)从该表中读取数据。然后,它将读取创建要发送给第三方的消息所需的每个表。将数据的提供者与数据的用户分离

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


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  
订阅表,如果第三方公司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  
第二部分是,将对库存的生命周期采取行动,这些行动也需要重新记录。在这种情况下,当库存状态发生变化时,将在同一队列中放置一条消息,并将该条目输入到同一个表中

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

这里的目标是不让业务层/数据层关心谁需要数据——只需要it提供数据,以便感兴趣的人能够获得数据


想知道是否有人做过类似的事情——有什么现成的开源解决方案可以做到这一点。

关于这个主题的高层讨论,我建议阅读Martin Fowler的文章

这听起来像是你写过一次,读过很多类型的数据,它可能会产生大量的数据,不同的客户机的数据是不同的。如果你问我,听起来这可能是一个利用NOSQL数据库或破解Oracle数据库以充当NOSQL数据库的好地方。有关某人如何使用MySQL实现这一点的讨论,请参阅

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

两件事

首先,你要自己做所有这些工作。JPA/Hibernate生命周期侦听器在更新发生时有一个事件,但不会向您传递“旧”对象和“新”对象。因此,您必须使用其他方法跟踪哪些字段发生了变化

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

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

但是如果你发布了大量的审计信息,那么这可能是一个问题

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


此外,如果可行,不要忽略使用DB触发器。在这个过程中,他们可能非常高效。

也许DBMS\u警报包会帮助您确定您喜欢的方法吗?我正在处理一个类似的场景,在这个主题上没有看到太多的文章。“我在使用生命周期侦听器中的JPA或JMS时遇到了“奇怪的”问题。”你是说将EntityManager注入到审计层是一个麻烦的来源吗?如果您决定不在生命周期侦听器中使用JPA,您是如何确定新旧实体之间的差异的?