Hibernate 在 Spring 应用程序中启用性能和事务管理

Hibernate Envers Performance and Transaction Management in a Spring Application

在我们的 SpringBoot 项目(使用 Spring MVC、Spring Data 等)中,我们使用 Hibernate Envers 来审计我们的数据库记录。 有几件事我不确定。

1- 性能 - 线程:

假设我有一个被审计的 Person 实体。当我 insert/update 相关 table 中的新 Person 记录时,这对我的应用程序性能有何影响?客户是否必须等待所有envers审计完成? Envers 会在单独的线程中处理这个吗?一旦插入成功,那么客户就可以继续他一直在做的任何任务了吗?还是所有审计都在一个线程中处理,客户端应用程序将不得不等待所有审计记录完成?

2-性能-缓存并执行:

Envers 会缓存所有审计处理并在以后执行吗?我的意思是在所有录制完成之后。

3- 交易管理:

事务管理怎么样。假设我已经成功地为 Person 实体创建了一条记录,但是在尝试创建审计记录时出现了错误。那会发生什么?这会回滚 Person 实体数据的记录吗?

4-分布式事务管理:

分布式事务环境如何?您将如何确保分布式事务环境中审计记录的一致性?您是否遇到过类似情况?如果遇到问题,您是如何解决的?

您在使用 Envers 时遇到过什么问题(如果有的话)。您应用了哪些替代审计方法?

请不要只提供链接然后说 "read this"。告诉我你所知道的和你经历过的。

非常感谢!

When I insert/update in the related table, how does this affect my app's performance?

Hibernate 有两种高级操作模式:有状态和无状态。

当 Hibernate 在有状态(例如 Session 而不是 StatelessSession)模式下运行时,它总是将实体操作收集到一个动作队列中。此操作队列稍后用于驱动事件系统,该系统不仅会导致 Hiberante 为这些操作执行 SQL,还会通知集成商这些实体操作。

行动队列有许多目标。但是在性能方面,它允许 Hibernate 收集这些操作并延迟数据库操作,以便最大限度地减少连接获取和使用,从而可以批量执行数据库操作。

Will the client have to wait for all the envers auditing to complete?
Envers handle this in a separate thread?

是的,客户端将不得不等待,因为 Envers 在与您的 Session.

相同的线程边界中运行

And once the insert is successful, then the client will be able to go on with whatever task he has been doing? Or will all that auditing be handled in a single thread and the client app will have to wait for all the audit recording to be completed?

Envers 维护着一个与 Hibernate 非常相似的操作队列。当 Hibernate 刷新其动作队列并触发事件时,Envers 将收到这些事件的通知,并将建立自己的动作队列。

Envers 的操作队列与 Hibernate 的主要区别在于,Envers 是一个提交时审计框架,它的操作队列不能手动刷新。审计操作队列将在事务提交之前立即自动刷新,以保证来自 Hibernate 的所有事务操作都已首先发送到数据库。

所以是的,它都是单线程的。

Does Envers cache all the audit processing and perform that at a later time? I mean after all the recording has been completed.

是的,如上所述,但我将在此处进行说明。假设我们在客户端中有一个打开的会话和一个活动的事务:

// User code calls save on some entity objects
// after these operations, some action queue entries are generated 
// No SQL has been executed
// No Audit operations have been executed or generated
session.save( someEntity1 );
session.save( someEntity2 );

// Lets say we manually flush Hibernate
// This flushes the Hibernate action queue
// SQL statements get fired for the above 2 saves
// Events are fired for integrators for the 2 save operations
// Envers generates AuditWorkUnit entries in its action queue for the operations
session.flush();

// User code calls save on another entity
// after these operations, some action queue entries are generated
// No SQL has been executed for this
// No Audit operations have been executed or generated
session.save( someEntity3 );

// commit the transaction
// This flueshes the Hibernate action queue
// sQL statements get fired for the above save of someEntity3
// Events are fired for integrators for the 1 save operation
// Envers generates AuditWorkUnit entries in its action queue for the operation
// pre-commit operations fire:
//   * Envers iterates its AuditWorkUnit action queue and executes those
//   * This generates Audit table SQL operations
// Transaction gets committed if no errors
session.getTransaction().commit();

How about transaction management. Let's say I have successfully created a record for the Person entity, but there was an error while trying to create the audit records. What would happen then? Would that rollback the recording of the Person entity data?

事务将被标记为回滚;因此,不会为 Person 或审计模式中的审计等价物保存任何数据。

How about a distributed transaction environment? How would you make sure the consistency of envers audit records in a distributed transaction environment? Have you ever been in a similar situation and how have you resolved your problems if any?

这不适用;让我解释一下。

Envers 本身非常简单。我之前提到的那些事件会导致生成一系列 HQL 语句并交给 Hibernate 执行;没什么特别的。

这意味着 SessionTransaction 您在客户端的用户代码中交互以将操作发送到 Hibernate 与 Envers 交互以执行完全相同的操作。

因此,如果该分布式事务因任何原因被标记为回滚,那么不仅您的 Person 数据会回滚,Envers 操作本身也会回滚。事务是否分布式与Hibernate与Envers的集成无关