【问题标题】:Creating a global transaction Id that is accessible through multiple packages创建可通过多个包访问的全局事务 ID
【发布时间】:2019-06-11 04:12:11
【问题描述】:

向所有 Java 专家致敬!

我正在开发一个新的、闪亮的流程可视化服务,我需要你的帮助!

我的项目结构是这样的:

Service Package 依赖于 Core Package,Core Package 又依赖于 Util 包。像这样的:

服务
|-|- 核心
|-|-|- 实用工具

应用程序包具有我们的代码开始的 main 方法。它正在调用一些使用 Util 包从输入中读取信息的核心方法。

package com.dummy.service;

public void main(Object input) {
     serviceCore.call(input);
}
package com.dummy.core;

public void call(Object input) {
     String stringInput = util.readFromInput(input);
     //Do stuff
}

package com.dummy.util;

public String readFromInput(Object input) {
     //return stuff;
}

当我想加入可视化服务时,问题就开始了。一项要求是对服务的每次调用使用唯一的事务 ID。

我的问题是 - 如何在所有这些方法之间共享进程 ID 而无需对代码进行过多重构?要在流程可视化工具中查看整个流程,我必须在整个调用中使用相同的 ID。我的愿景是:

package com.dummy.service;

public void main(Object input) {
     processVisualization.signal(PROCESS_ID, "transaction started");
     serviceCore.call(input);
     processVisualization.signal(PROCESS_ID, "transaction ended");
}
package com.dummy.core;

public void call(Object input) {
     processVisualization.signal(PROCESS_ID, "Method call is invoked");
     String stringInput = util.readFromInput(input);
     //Do stuff
}

package com.dummy.util;

public String readFromInput(Object input) {
     processVisualization.signal(PROCESS_ID, "Reading from input");
     //return stuff;
}

我正在考虑以下内容,但所有这些都只是抽象的想法,我什至不确定是否可以实现。如果是 - 那怎么办?

  1. 创建一个所有三个包都将依赖的新包,并为每个调用“保留”进程 ID。但是怎么做?我应该在这个包中使用静态类吗?单身狗?

  2. 我读过这篇关于 ThreadLocal 变量的帖子:When and how should I use a ThreadLocal variable?,但我不熟悉这些,也不知道如何实现这个想法 - 是否应该像我在 1 中提到的那样放到单独的包中?

  3. 更改方法的签名以将 id 作为变量传递。不幸的是,就时间和大规模重构的危险而言,这太昂贵了。

  4. 使用文件写入 - 将 ID 保存在可在整个过程中访问的某个文件中。

  5. 从输入构造一个唯一的 id - 我认为这可能是完美的解决方案,但我们可能会在对服务的单独调用中收到相同的输入。

  6. 访问 JVM 以获得一些唯一的事务 ID。我知道当我们记录东西时,我们在日志行中打印了 RequestId。这是我们在 Log4J 配置中使用的模式: <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} %highlight{[%p]} %X{RequestId} (%t) %c: %m%n</pattern> 此 RequestId 是在作业之前创建的 ThreadContext 上的变量。是否可以和/或建议访问此参数并将其用作唯一的事务 ID?

【问题讨论】:

    标签: java static transactions thread-local


    【解决方案1】:

    最后我们使用了 Log4J 的线程上下文。 这可能不是最好的解决方案,因为我们混合了同一件事的目的,但我们就是这样做的:

    进程ID是这样提取的: org.apache.logging.log4j.ThreadContext.get("RequestId");

    并在 Handler Chain 上启动(取决于您使用的服务): ThreadContext.put("RequestId", Objects.toString(job.getId(), (String)null));
    这发生在收到的每份工作上。

    免责声明:此解决方案尚未经过全面测试,但这是我们的方向

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      相关资源
      最近更新 更多