事务问题之跨服务获取不到未提交事务的值的解决方法

得闲饮茶 / 2024-09-14 / 原文

事件背景

在配置流程定义完成后,我们遇到了一个棘手的问题:在提交审批后,某个流程变量无法被获取。简而言之,在服务A中,提交审批事务时,新增数据的主键作为工作流的KEY传递给服务B,但服务B中该KEY值为null。

思考

究竟是什么导致了这个现象?难道是某种神秘力量?

解决过程

首先,我们采取了常规的调试手段——设置断点。在工作流方法处,我们发现返回的新增对象确实有值。进一步查询数据库,却发现该数据并不存在。这引导我们去检查数据库的隔离级别。

官方解释

我们了解到,数据库的隔离级别是 REPEATABLE READ(可重复读),它确保在同一个事务中,多次读取同一数据的结果是一致的,除非数据是被当前事务自己修改的。这意味着,在事务A提交之前,事务B无法看到未提交的插入操作。

问题根源

经过分析,我们发现问题的根本原因是事务未提交。除了这一点,其他可能的原因还包括缓存、延迟更新、数据库触发器等,但由于时间关系,我们没有进一步深入。

解决方案

为了避免这个问题,我们采用了以下方法:

import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class MyService {
    public void someTransactionalMethod() {
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                // 回调方法,确保在事务提交后执行
            }
        });
    }
}

在Spring框架中,TransactionSynchronizationManager 是一个用于管理事务同步的组件。通过注册同步操作,我们可以确保在事务的生命周期事件(如事务的开始和结束)中执行特定的操作。这避免了在事务未提交时获取不到KEY值的问题。

当然以上解决的办法以及遇到问题的场景比较片面,后面有时间会拓展一下填上这个坑。