当前位置: 首页 > 知识库问答 >
问题:

Spring应用程序中的Hibernate Envers性能和事务管理

毕泽宇
2023-03-14

在我们的SpringBoot项目(使用SpringMVC、SpringData等)中,我们使用HibernateEnvers来审核数据库记录。有几件事我不确定。

1-性能-线程:

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

2-性能-缓存和do:

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

3-事务管理:

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

4-分布式事务管理:

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

您在使用Envers时遇到了哪些问题(如果有)。您采用的其他审计方法有哪些?

请不要只是提供链接和说“读这个”。告诉我你知道什么,你经历过什么。

谢谢!

共有1个答案

邴宏大
2023-03-14

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

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

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

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

客户端是否需要等待所有的审计完成?
Envers在一个单独的线程中处理这个?

是的,当Envers与您的会话运行在同一线程边界时,客户端必须等待。

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

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();

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

事务将被标记为回滚;因此不会为Person保存任何数据,也不会在审计架构中为它保存审计等价物。

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

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

Envers本身就是超级简单化的。我前面提到的这些事件导致生成一系列HQL语句并将其交给Hibernate执行;没有什么特别的。

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

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

 类似资料:
  • Spring Transaction不支持多线程,所以我尝试在thread的run()方法中手动管理事务。但是,没用! 我想在下面的示例中回滚每个线程的run()方法,当其中有异常抛出时。(在以下情况下,插入到UNKNOWN_TABLE) 我的预期结果是“开始,1,3,5,结束”。 而实际结果是‘开始,1,2,3,4,5,结束’。 欢迎任何回复!谢谢! 主要类别: 服务等级:

  • 在基于Spring的应用程序中,事务管理器负责提交或回滚SQL事务。我的应用程序对持久性数据的某些部分使用自定义缓存。这个缓存不是由Spring或Hibernate管理的。 如果SQL事务遇到错误并且必须回滚,那么缓存修改也应该回滚。 我的问题是,当Spring Transaction Manager回滚事务时,如何注册一个将调用我的方法的事件侦听器或回调?

  • 问题内容: 我正在使用Callable接口在serviceImpl中编写多线程程序。我正在使用spring事务管理器。在DB中执行更新操作时,它会成功执行。但是更新后的数据不会反映在DB中。但是,当我运行不带多线程的程序时,它将在DB中更新。 这是我的配置 我可以转向事务管理器的另一种方法。只是我想确认这种方法是否支持多线程。所以我的问题是 spring事务管理器是否支持多线程(我的意思是仅通过声

  • 问题内容: 我们正在一个小型Web(将在Tomcat上运行)上工作,并使用JPA(Eclipselink)来完成数据层。我前段时间做过类似的事情。但是我总是不确定何时需要开始和结束交易或进行刷新。目前我使用事务(如果我添加(持久)并删除对象)。如果我在已经存在的对象上调用设置器,则不使用事务。 什么时候使用事务或如何正确实现应用程序管理的JPA,是否有指南/教程或简短答案。 问题答案: 我认为可以

  • 我有一个非常基本的Spring Boot应用程序,它公开了一个非常简单的实体的CRUD Rest API。使用JMeter运行性能测试显示响应时间很差 约束:id PK自动增量 设置: 线程数:100 4个API,用于执行以下功能 我试图用可视化虚拟机查看原因。似乎存储库函数花费了太多时间。我假设是数据库导致了这个问题。 连接池设置:因为我没有设置任何内容,假设我的应用程序使用HikariCP,默

  • 在db会话监视器中,当这种情况发生时,我得到了一个不活动的事务。 我得到的错误如下: 问题是交易和连接应该自动打开和关闭...我希望并发修改失败的事务得到回滚...但似乎他们变得不活跃了。