【问题标题】:Async auditing with JaVers使用 JaVers 进行异步审计
【发布时间】:2017-10-12 03:31:49
【问题描述】:

我需要审核我们应用程序中某些实体的更改,并且正在考虑使用 JaVers。我喜欢 JaVers 提供的对查询审计数据的支持。 Hibernate Envers 看起来不错,但它会将数据存储在同一个数据库中。

这是我的要求:

  • 异步日志记录 - 将性能影响降至最低
  • 将审计数据存储在不同的数据库中 - 也是性能原因

据我所知,JaVers 不是为上述目的而设计的,但似乎可以适应实现上述目的。方法如下:

  • JaVers 实际上允许将数据存储在不同的数据库中。您可以真正提供与任何数据库的连接。这不是它的意图,但它有效。下面的代码(注意 connectionProvider 可以提供到任何数据库的连接):

'

final Connection dbConnection =
            DriverManager.getConnection("jdbc:mysql://localhost:3306/javers", "root", "root");

ConnectionProvider connectionProvider = new ConnectionProvider() {
    @Override
    public Connection getConnection() {
        //suitable only for testing!
        return dbConnection;
    }
};
JaversSqlRepository sqlRepository = SqlRepositoryBuilder
            .sqlRepository()
            .withConnectionProvider(connectionProvider)
            .withDialect(DialectName.MYSQL).build();
  • 可以通过将 JaVers 提交的执行移到线程/执行器中来实现异步。挑战在于,如果执行时间过长,则可能是对象在记录之前发生了变化。我可以在这里想到两种解决方案:
    • 我们可以创建对象的快照(例如,将其序列化为 JSON 等)并将其传递给线程以记录它。
    • 我们提供了 Javers Repository 的自定义实现,它处理当前线程中的差异,然后将 Snapshot 对象传递到另一个线程中持久化。这样,我们只需要在应用程序线程中读取 DB,并在 Auditing 线程中写入(这通常在性能方面成本更高)。

问题:

  • 我在这里遗漏了什么吗?这行得通吗?
  • JaVers 是否支持创建对象的快照,然后可以将其移动到另一个线程。它在内部某个地方执行此操作,所以也许我们可以使用它。

仅供参考:与该问题无关,但以下是我能想到的其他一些挑战以及我打算如何解决它们:

  • 由于不在同一个事务中进行审计,如果事务失败,它会使审计回滚变得复杂。所以我们只需要审核成功提交的对象。我打算通过使用 Hibernate 拦截器、监听 afterTransactionCompletion 并仅提交由该事务更新的对象来做到这一点。
  • 对于延迟加载的对象,我可以看到,如果我们在事务完成后尝试访问它们,可能是无法访问延迟加载的道具(因为会话也可能关闭) - 不知道如何解决这个问题,但这可能不是问题,因为我认为我们正在加载大多数道具。

【问题讨论】:

  • 异步提交已在 3.12.0 版本中发布

标签: java javers


【解决方案1】:

有趣的问题。 首先是痴呆。所有 JaVers 核心模块都旨在将审计数据与应用程序数据分离。正如您所提到的,用户提供了一个供 JaVers 使用的 ConnectionProvider。它可以是您想要的任何数据库。

不适合与多个数据库一起使用的是用于 SQL 的 Spring 集成模块,因此 javers-spring-jpajavers-spring-boot-starter-sql。它们仅涵盖最常见的场景,因此应用程序和 JaVers 使用相同的数据库。

关于缺少异步提交,你是对的。幸运的是,它只能在JaversCore 中实现,而无需更改存储库。

API 可以是:

CompletableFuture<Commit> javers.commitAsync(..., Executor);

首先,Javers 会拍摄用户对象的快照,速度很快,因此可以在当前线程中完成。

然后,数据库读取(加载最新快照)和数据库写入(插入新快照)可以异步完成(提交给给定的 Executor)。

正如您所提到的,它需要数据库事务的新方法。我们计划实现 Commit Withdrawal 功能,以便应用能够在主数据库回滚后撤回 JaVers 的提交。见https://github.com/javers/javers/issues/588

【讨论】:

  • 谢谢,听起来不错。为了让它更有趣,我们也在使用 Java 7,并且怀疑我们是否能够过早地改变(这是一个相当复杂的 10 多年前的应用程序,所以改变发生得非常缓慢)。可以在以前的版本中进行更改吗?另外,您真的打算添加异步支持吗?
  • 我很乐意将代码移植到最新版本的 JaVers 中。
  • 我们不会开发 JaVers 2.9.2(与 Java 7 兼容的最新版本)。自 2.9.2 以来,我们进行了很多更改和重构,因此将 JaVers 3.6 的功能移回 2.9 将是一场噩梦。没有关于异步提交的计划,认为我们可以在提交撤消后进行,可能是一月份
  • 你好@BartekWalacik,有没有计划为 SQL 包括 Asnc 提交。我们已经实施了 JaVers (javers-spring-boot-starter-sql) 来审计我们以前的项目之一,现在我们面临一些性能问题,现在我们正在为我们的新项目寻找替代选项。 JaVers 提供了除性能之外的所有优秀功能。
  • @AsifKarimBherani 暂时没有这样的计划,创建问题github.com/javers/javers/issues,我们可以考虑一下
猜你喜欢
  • 2019-11-08
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
  • 2018-04-18
  • 2019-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多