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

Sof*_*ory 1 hibernate hibernate-envers

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

1- 性能 - 线程:

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

2- 性能 - 缓存并执行:

Envers 是否缓存所有审计处理并在稍后执行?我的意思是在所有录音都完成之后。

3- 交易管理:

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

4-分布式事务管理:

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

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

请不要只提供链接并说“阅读此内容”。告诉我你所知道的和你所经历的。

非常感谢!

Nar*_*ros 6

当我在相关表中插入/更新时,这如何影响我的应用程序的性能?

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

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

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

客户是否必须等待所有环境审计完成?
Envers 在一个单独的线程中处理这个?

是的,当 Envers 在与您的Session.

一旦插入成功,那么客户就可以继续他一直在做的任何任务?或者所有审计都在一个线程中处理,客户端应用程序将不得不等待所有审计记录完成?

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

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

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

Envers 是否缓存所有审计处理并在稍后执行?我的意思是在所有录音都完成之后。

是的,正如我上面所描述的,但我将在这里说明。让我们假设我们有一个打开的会话和一个我们正在客户端中使用的活动事务:

// 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();
Run Code Online (Sandbox Code Playgroud)

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

事务将被标记为回滚;因此,不会Person在审计模式中为其保存任何数据或对其进行等效审计。

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

这不适用;让我解释。

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

这意味着什么是相同的,Session并且Transaction您在客户端的用户代码中与之交互以将操作发送到 Hibernate 与 Envers 与之交互以执行完全相同的操作相同。

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