分布式事务Seata使用不当引发的全局锁问题
报错信息
2025-08-12T19:36:27.803+08:00 ERROR 1 --- [xxx-inference] [io-32123-exec-7] o.a.s.r.d.exec.AbstractDMLBaseExecutor : execute executeAutoCommitTrue error:Global lock wait timeout org.apache.seata.rm.datasource.exec.LockWaitTimeoutException: Global lock wait timeout at org.apache.seata.rm.datasource.exec.LockRetryController.sleep(LockRetryController.java:66) ~[seata-all-2.1.0.jar!/:2.1.0] at org.apache.seata.rm.datasource.ConnectionProxy$LockRetryPolicy.doRetryOnLockConflict(ConnectionProxy.java:364) ~[seata-all-2.1.0.jar!/:2.1.0] at org.apache.seata.rm.datasource.exec.AbstractDMLBaseExecutor$LockRetryPolicy.execute(AbstractDMLBaseExecutor.java:188) ~[seata-all-2.1.0.jar!/:2.1.0]
错误代码示例
@GlobalTransactional
public void deletePod(PodBo podBo) {KubernetesClient kubernetesClient = k8SClientMgr.getConnect("", true);ModelServiceEntity modelServiceEntity = modelServiceMapper.selectById(podBo.getServiceId());if (modelServiceEntity == null) {throw new RuntimeException("模型服务不存在");}if (podBo.getServiceId() != null) {UpdateWrapper<ModelServiceEntity> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("id", podBo.getServiceId());updateWrapper.set("status", 1);modelServiceMapper.update(null, updateWrapper);// 远程调用删除任务inferenceTaskApi.deleteInferenceTask(Arrays.asList(modelServiceEntity.getInferenceTaskId().split(",")));}ResourceDefinitionContext context = new ResourceDefinitionContext.Builder().withGroup("kubeai.org").withVersion("v1").withPlural("models").withKind("Model").withNamespaced(true).build();// 删除 CRD 资源kubernetesClient.genericKubernetesResources(context).inNamespace(namespace).withName(podBo.getName().toLowerCase()).delete();
}
问题分析
// 这里查询了model_service表,seata会对model_service表进行加锁
ModelServiceEntity modelServiceEntity = modelServiceMapper.selectById(podBo.getServiceId());// 这里又进行了修改操作,由于前面已经加锁了,导致这里无法执行成功,进而超时
modelServiceMapper.update(null, updateWrapper);
问题解决
查询逻辑和更新逻辑不在一个事务里执行即可
public void deletePod(PodBo podBo) {KubernetesClient kubernetesClient = k8SClientMgr.getConnect("", true);ModelServiceEntity modelServiceEntity = modelServiceMapper.selectById(podBo.getServiceId());if (modelServiceEntity == null) {throw new RuntimeException("模型服务不存在");}deleteResource(kubernetesClient, podBo, modelServiceEntity);
}@GlobalTransactional
public void deleteResource(KubernetesClient kubernetesClient, PodBo podBo, ModelServiceEntity modelServiceEntity) {if (podBo.getServiceId() != null) {UpdateWrapper<ModelServiceEntity> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("id", podBo.getServiceId());updateWrapper.set("status", 1);modelServiceMapper.update(null, updateWrapper);// 远程调用删除任务inferenceTaskApi.deleteInferenceTask(Arrays.asList(modelServiceEntity.getInferenceTaskId().split(",")));}ResourceDefinitionContext context = new ResourceDefinitionContext.Builder().withGroup("kubeai.org").withVersion("v1").withPlural("models").withKind("Model").withNamespaced(true).build();// 删除 CRD 资源kubernetesClient.genericKubernetesResources(context).inNamespace(namespace).withName(podBo.getName().toLowerCase()).delete();
}