/** * inti service. */ public void init(TxConfig txConfig) { Runtime.getRuntime().addShutdownHook( new Thread(() -> LOGGER.error("raincat init error"))); try { initService.initialization(txConfig); } catch (RuntimeException ex) { LogUtil.error(LOGGER, "raincat init exception:{}", ex::getMessage); //非正常关闭 System.exit(1); } }
private synchronized void updateTxManagerServices() { String url = assembleUrl(); int maxRetries = 2; for (int i = 0; i < maxRetries; i++) { try { final List<TxManagerServiceDTO> serviceDTOList = OkHttpTools.getInstance().get(url, type); if (CollectionUtils.isEmpty(serviceDTOList)) { LogUtil.error(LOGGER, "Empty response! 请求url为:{}", () -> url); continue; } listAtomicReference.set(serviceDTOList); return; } catch (Throwable ex) { LogUtil.error(LOGGER, "updateTxManagerServices fail exception:{}", ex::getMessage); } } }
@Override public Object interceptor(final ProceedingJoinPoint pjp) throws Throwable { final String compensationId = CompensationLocal.getInstance().getCompensationId(); String groupId = null; if (StringUtils.isBlank(compensationId)) { //如果不是本地反射调用补偿 try { RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); groupId = request.getHeader(CommonConstant.TX_TRANSACTION_GROUP); } catch (IllegalStateException e) { LogUtil.error(LOGGER,"Not Http request ,can't get RequestContextHolder!", e::getMessage); } } return aspectTransactionService.invoke(groupId, pjp); }
/** * acquire tx manage info. * * @return {@linkplain TxManagerServer} */ public TxManagerServer locator() { int maxRetries = 2; final List<TxManagerServiceDTO> txManagerService = getTxManagerService(); if (CollectionUtils.isEmpty(txManagerService)) { return null; } for (int i = 0; i < maxRetries; i++) { List<TxManagerServiceDTO> randomServices = Lists.newLinkedList(txManagerService); Collections.shuffle(randomServices); for (TxManagerServiceDTO serviceDTO : randomServices) { String url = String.join("", serviceDTO.getHomepageUrl(), CommonConstant.TX_MANAGER_PRE, CommonConstant.FIND_SERVER); LOGGER.debug("Loading service from {}", url); try { return OkHttpTools.getInstance().get(url, null, TxManagerServer.class); } catch (Throwable ex) { ex.printStackTrace(); LogUtil.error(LOGGER, "loadTxManagerServer fail exception:{}", ex::getMessage); } } } return null; }
@Override public void init(final String appName, final TxConfig txConfig) { keyName = RepositoryPathUtils.buildRedisKey(appName); final TxRedisConfig txRedisConfig = txConfig.getTxRedisConfig(); try { buildJedisClient(txRedisConfig); } catch (Exception e) { LogUtil.error(LOGGER, "redis init exception please check your config :{}", e::getMessage); } }
@Override public void init(final String appName, final TxConfig txConfig) { setRootPath(RepositoryPathUtils.buildZookeeperPath(appName)); try { connect(txConfig.getTxZookeeperConfig()); } catch (Exception e) { LogUtil.error(LOGGER, "zookeeper init exception please check you config:{}", e::getMessage); throw new TransactionRuntimeException(e.getMessage()); } }
for (TransactionRecover transactionRecover : transactionRecovers) { if (transactionRecover.getRetriedCount() > txConfig.getRetryMax()) { LogUtil.error(LOGGER, "此事务超过了最大重试次数,不再进行重试:{}", () -> transactionRecover.getTransactionInvocation().getTargetClazz().getName() + ":" + transactionRecover.getTransactionInvocation().getMethod() + "事务组id:" + transactionRecover.getGroupId()); LogUtil.error(LOGGER, "执行事务补偿异常:{}", e::getMessage);
@SuppressWarnings("unchecked") private void compensatoryTransfer(final TransactionRecover transactionRecover) { if (Objects.nonNull(transactionRecover)) { final TransactionInvocation transactionInvocation = transactionRecover.getTransactionInvocation(); if (Objects.nonNull(transactionInvocation)) { final Class clazz = transactionInvocation.getTargetClazz(); final String method = transactionInvocation.getMethod(); final Object[] argumentValues = transactionInvocation.getArgumentValues(); final Class[] argumentTypes = transactionInvocation.getArgumentTypes(); final Object bean = SpringBeanUtils.getInstance().getBean(clazz); try { CompensationLocal.getInstance().setCompensationId(CommonConstant.COMPENSATE_ID); MethodUtils.invokeMethod(bean, method, argumentValues, argumentTypes); //通知tm自身已经完成提交 //删除本地信息 final Boolean success = txManagerMessageService.completeCommitTxTransaction(transactionRecover.getGroupId(), transactionRecover.getTaskId(), TransactionStatusEnum.COMMIT.getCode()); if (success) { transactionRecoverRepository.remove(transactionRecover.getId()); } } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); LogUtil.error(LOGGER, "补偿方法反射调用失败!{}", e::getMessage); } } } }
LogUtil.error(LOGGER, () -> "预提交失败!");
private TransactionRecover buildByCache(final MongoAdapter cache) { TransactionRecover recover = new TransactionRecover(); recover.setId(cache.getTransId()); recover.setCreateTime(cache.getCreateTime()); recover.setGroupId(cache.getGroupId()); recover.setTaskId(cache.getTaskId()); recover.setLastTime(cache.getLastTime()); recover.setRetriedCount(cache.getRetriedCount()); recover.setVersion(cache.getVersion()); recover.setStatus(cache.getStatus()); recover.setCompleteFlag(cache.getCompleteFlag()); recover.setOperation(cache.getOperation()); final TransactionInvocation transactionInvocation; try { transactionInvocation = objectSerializer.deSerialize(cache.getContents(), TransactionInvocation.class); recover.setTransactionInvocation(transactionInvocation); } catch (TransactionException e) { LogUtil.error(LOGGER, "mongodb serialize exception:{}", e::getLocalizedMessage); } return recover; }