[seata]store.mode=db 事务结束后globalsession的状态未正确修改为commited

2024-04-28 819 views
6

saga模式下 store.mode = db 事务结束后globalsession的状态未正确修改为commited,依然还是begin,导致global表中状态为1,等待1800s后会对事务进行回滚; SessionHelper中endCommitted的中的

    public static void endCommitted(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
        if (retryGlobal || !DELAY_HANDLE_SESSION) {
            long beginTime = System.currentTimeMillis();
            boolean retryBranch = globalSession.getStatus() == GlobalStatus.CommitRetrying;
            globalSession.changeGlobalStatus(GlobalStatus.Committed);
            globalSession.end();
            if (!DELAY_HANDLE_SESSION) {
                MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
            }
            MetricsPublisher.postSessionDoneEvent(globalSession, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY, true,
                beginTime, retryBranch);
        } else {
            MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
        }
    }

store.mode = db 时DELAY_HANDLE_SESSION为true,进不了分支,导致不能changeGlobalStatus为Committed

把DELAY_HANDLE_SESSION的取反去掉

回答

7

这是特意做的延迟删除,在非at模式下会set一个内存的status让committed打点成功,saga这块漏掉了,你可以提个pr来修复这个问题吗? image

9

我看了一下,是在SagaCore的doGlobalCommit方法中也添加这个判断嘛? 我可以试试吗?

6

把 if(!retring){ globalsession.setStatus(Committed) } 放到 if(success && globalSession.getBranchsessions().isempty){

} 里面是不是就通用了?

6

image 这里已经把状态改成了Committing,不会是Begin,这里解决的问题应该只是saga模式下metrics没有打Committed点的问题

9

请教下,这里的延迟删除指的是延迟删除Brach事务吧,理论上不应该io.seata.server.session.SessionHelper#endCommitted改这块吧~

1

这里的延迟删除是一种兜底策略,延迟删除GlobalSession,防止有残留的锁和Branch在GlobalSession被删除后没有全局事务关联他们,导致这些残留的锁和Branch一直存在