前面的博客中,我们介绍了,发起全局事务时,是如何进行全局事务提交的,这篇博客,主要记录,在seata分布式事务中,全局事务提交的时候,服务端是如何进行处理的
发起全局事务提交操作
事务发起者,在所有分支事务执行完毕之后,如果没有发生异常,会进行全局事务提交
这里就不做过多解释了,前面seata入门和全局事务begin的博客中,有介绍过这里入参的request对象的重要性
服务端接收到请求
前面全局事务begin的源码,介绍过,netty服务端接收到请求之后,是如何执行到这里的,在这里会根据request请求的类型,交给不同的handler来处理
io.seata.server.AbstractTCInboundHandler#handle(io.seata.core.protocol.transaction.GlobalCommitRequest, io.seata.core.rpc.RpcContext)
io.seata.server.coordinator.DefaultCoordinator#doGlobalCommit
上面也没有太多的业务逻辑,没什么好说的,我们直接来看core.commit()方法的逻辑
io.seata.server.coordinator.DefaultCore#commit
@Override
public GlobalStatus commit(String xid) throws TransactionException {
/**
* 1.获取全局session:globalSession
*/
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
if (globalSession == null) {
return GlobalStatus.Finished;
}
/**
* 2.给globalSession添加监听
*/
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
// just lock changeStatus
/**
* 3.对globalSession进行一些处理
*/
boolean shouldCommit = SessionHolder.lockAndExecute(globalSession, () -> {
// Highlight: Firstly, close the session, then no more branch can be registered.
/**
* 3.1 globalSession.setActive(false);将全局session的active设置为false
* 在clean()方法中会把lockTable中本次加锁的记录(分支事务相关锁信息)删除
*/
globalSession.closeAndClean();
if (globalSession.getStatus() == GlobalStatus.Begin) {
/**
* 对于AT模式,这里永远返回false
* 对于AT模式,这里会执行if的逻辑,将globalSession的status设置为AsyncCommitting
*/
if (globalSession.canBeCommittedAsync()) {
globalSession.asyncCommit();
return false;
} else {
/**
* 将globalSession的状态设置为committing状态
*/
globalSession.changeStatus(GlobalStatus.Committing);
return true;
}
}
return false;
});
/**
* 4.通知分支事务进行提交,如果是AT模式,不会进入到这里执行,因为shouldCommit是false
* 是通过一个异步线程来进行调用doGlobalCommit()方法的
*/
if (shouldCommit) {
boolean success = doGlobalCommit(globalSession, false);
//If successful and all remaining branches can be committed asynchronously, do async commit.
if (success && globalSession.hasBranch(<