/** * add participant. * * @param hmilyParticipant {@linkplain HmilyParticipant} */ public void enlistParticipant(final HmilyParticipant hmilyParticipant) { if (Objects.isNull(hmilyParticipant)) { return; } Optional.ofNullable(getCurrentTransaction()) .ifPresent(c -> { c.registerParticipant(hmilyParticipant); updateParticipant(c); }); }
@Override public Object handler(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable { Object returnValue; try { HmilyTransaction hmilyTransaction = hmilyTransactionExecutor.preTry(point); try { //execute try returnValue = point.proceed(); hmilyTransaction.setStatus(HmilyActionEnum.TRYING.getCode()); hmilyTransactionExecutor.updateStatus(hmilyTransaction); } catch (Throwable throwable) { //if exception ,execute cancel final HmilyTransaction currentTransaction = hmilyTransactionExecutor.getCurrentTransaction(); executor.execute(() -> hmilyTransactionExecutor .cancel(currentTransaction)); throw throwable; } //execute confirm final HmilyTransaction currentTransaction = hmilyTransactionExecutor.getCurrentTransaction(); executor.execute(() -> hmilyTransactionExecutor.confirm(currentTransaction)); } finally { HmilyTransactionContextLocal.getInstance().remove(); hmilyTransactionExecutor.remove(); } return returnValue; }
private void executeHandler(final boolean success, final HmilyTransaction currentTransaction, final List<HmilyParticipant> failList) { HmilyTransactionGuavaCacheManager.getInstance().removeByKey(currentTransaction.getTransId()); if (success) { deleteTransaction(currentTransaction); } else { currentTransaction.setHmilyParticipants(failList); updateParticipant(currentTransaction); throw new HmilyRuntimeException(failList.toString()); } }
final HmilyParticipant hmilyParticipant = buildParticipant(hmily, method, args, hmilyTransactionContext); if (hmilyTransactionContext.getRole() == HmilyRoleEnum.INLINE.getCode()) { hmilyTransactionExecutor.registerByNested(hmilyTransactionContext.getTransId(), hmilyParticipant); } else { hmilyTransactionExecutor.enlistParticipant(hmilyParticipant);
case TRYING: try { hmilyTransaction = hmilyTransactionExecutor.preTryParticipant(context, point); final Object proceed = point.proceed(); hmilyTransaction.setStatus(HmilyActionEnum.TRYING.getCode()); hmilyTransactionExecutor.updateStatus(hmilyTransaction); return proceed; } catch (Throwable throwable) { hmilyTransactionExecutor.deleteTransaction(hmilyTransaction); throw throwable; } finally { currentTransaction = HmilyTransactionGuavaCacheManager .getInstance().getHmilyTransaction(context.getTransId()); hmilyTransactionExecutor.confirm(currentTransaction); break; case CANCELING: currentTransaction = HmilyTransactionGuavaCacheManager .getInstance().getHmilyTransaction(context.getTransId()); hmilyTransactionExecutor.cancel(currentTransaction); break; default:
deleteTransaction(currentTransaction); return; final List<HmilyParticipant> hmilyParticipants = filterPoint(currentTransaction); boolean success = true; List<HmilyParticipant> failList = Lists.newArrayListWithCapacity(hmilyParticipants.size()); currentTransaction.setStatus(HmilyActionEnum.CANCELING.getCode()); updateStatus(currentTransaction); for (HmilyParticipant hmilyParticipant : hmilyParticipants) { try { context.setRole(HmilyRoleEnum.START.getCode()); HmilyTransactionContextLocal.getInstance().set(context); executeParticipantMethod(hmilyParticipant.getCancelHmilyInvocation()); } catch (Throwable e) { LogUtil.error(LOGGER, "execute cancel ex:{}", () -> e); executeHandler(success, currentTransaction, failList);
@Override public Object handler(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable { if (HmilyActionEnum.TRYING.getCode() == context.getAction()) { MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); Class<?> clazz = point.getTarget().getClass(); Object[] args = point.getArgs(); final Hmily hmily = method.getAnnotation(Hmily.class); HmilyInvocation confirmInvocation = null; String confirmMethodName = hmily.confirmMethod(); String cancelMethodName = hmily.cancelMethod(); if (StringUtils.isNoneBlank(confirmMethodName)) { confirmInvocation = new HmilyInvocation(clazz, confirmMethodName, method.getParameterTypes(), args); } HmilyInvocation cancelInvocation = null; if (StringUtils.isNoneBlank(cancelMethodName)) { cancelInvocation = new HmilyInvocation(clazz, cancelMethodName, method.getParameterTypes(), args); } final HmilyParticipant hmilyParticipant = new HmilyParticipant(context.getTransId(), confirmInvocation, cancelInvocation); hmilyTransactionExecutor.registerByNested(context.getTransId(), hmilyParticipant); } return point.proceed(); }
updateStatus(currentTransaction); final List<HmilyParticipant> hmilyParticipants = currentTransaction.getHmilyParticipants(); List<HmilyParticipant> failList = Lists.newArrayListWithCapacity(hmilyParticipants.size()); context.setTransId(hmilyParticipant.getTransId()); HmilyTransactionContextLocal.getInstance().set(context); executeParticipantMethod(hmilyParticipant.getConfirmHmilyInvocation()); } catch (Exception e) { LogUtil.error(LOGGER, "execute confirm :{}", () -> e); executeHandler(success, currentTransaction, failList);
@SuppressWarnings("unchecked") private HmilyParticipant buildParticipant(final HmilyTransactionContext hmilyTransactionContext, final Hmily hmily, final Method method, final Class clazz, final Object[] arguments, final Class... args) throws HmilyRuntimeException { if (Objects.isNull(hmilyTransactionContext) || (HmilyActionEnum.TRYING.getCode() != hmilyTransactionContext.getAction())) { return null; } String confirmMethodName = hmily.confirmMethod(); if (StringUtils.isBlank(confirmMethodName)) { confirmMethodName = method.getName(); } String cancelMethodName = hmily.cancelMethod(); if (StringUtils.isBlank(cancelMethodName)) { cancelMethodName = method.getName(); } final PatternEnum pattern = hmily.pattern(); SpringBeanUtils.getInstance().getBean(HmilyTransactionExecutor.class) .getCurrentTransaction().setPattern(pattern.getCode()); HmilyInvocation confirmInvocation = new HmilyInvocation(clazz, confirmMethodName, args, arguments); HmilyInvocation cancelInvocation = new HmilyInvocation(clazz, cancelMethodName, args, arguments); return new HmilyParticipant(hmilyTransactionContext.getTransId(), confirmInvocation, cancelInvocation); } }
/** * this is Participant transaction preTry. * * @param context transaction context. * @param point cut point * @return TccTransaction */ public HmilyTransaction preTryParticipant(final HmilyTransactionContext context, final ProceedingJoinPoint point) { LogUtil.debug(LOGGER, "participant hmily transaction start..:{}", context::toString); final HmilyTransaction hmilyTransaction = buildHmilyTransaction(point, HmilyRoleEnum.PROVIDER.getCode(), context.getTransId()); //cache by guava HmilyTransactionGuavaCacheManager.getInstance().cacheHmilyTransaction(hmilyTransaction); //publishEvent hmilyTransactionEventPublisher.publishEvent(hmilyTransaction, EventTypeEnum.SAVE.getCode()); //Nested transaction support context.setRole(HmilyRoleEnum.LOCAL.getCode()); HmilyTransactionContextLocal.getInstance().set(context); return hmilyTransaction; }
/** * when nested transaction add participant. * * @param transId key * @param hmilyParticipant {@linkplain HmilyParticipant} */ public void registerByNested(final String transId, final HmilyParticipant hmilyParticipant) { if (Objects.isNull(hmilyParticipant) || Objects.isNull(hmilyParticipant.getCancelHmilyInvocation()) || Objects.isNull(hmilyParticipant.getConfirmHmilyInvocation())) { return; } final HmilyTransaction hmilyTransaction = HmilyTransactionGuavaCacheManager.getInstance().getHmilyTransaction(transId); Optional.ofNullable(hmilyTransaction) .ifPresent(transaction -> { transaction.registerParticipant(hmilyParticipant); updateParticipant(transaction); }); }
final HmilyParticipant hmilyParticipant = buildParticipant(hmilyTransactionContext, hmily, method, clazz, arguments, args); if (hmilyTransactionContext.getRole() == HmilyRoleEnum.INLINE.getCode()) { hmilyTransactionExecutor.registerByNested(hmilyTransactionContext.getTransId(), hmilyParticipant); } else { hmilyTransactionExecutor.enlistParticipant(hmilyParticipant);
/** * transaction preTry. * * @param point cut point. * @return TccTransaction */ public HmilyTransaction preTry(final ProceedingJoinPoint point) { LogUtil.debug(LOGGER, () -> "......hmily transaction starter...."); //build tccTransaction final HmilyTransaction hmilyTransaction = buildHmilyTransaction(point, HmilyRoleEnum.START.getCode(), null); //save tccTransaction in threadLocal CURRENT.set(hmilyTransaction); //publishEvent hmilyTransactionEventPublisher.publishEvent(hmilyTransaction, EventTypeEnum.SAVE.getCode()); //set TccTransactionContext this context transfer remote HmilyTransactionContext context = new HmilyTransactionContext(); //set action is try context.setAction(HmilyActionEnum.TRYING.getCode()); context.setTransId(hmilyTransaction.getTransId()); context.setRole(HmilyRoleEnum.START.getCode()); HmilyTransactionContextLocal.getInstance().set(context); return hmilyTransaction; }
final HmilyParticipant hmilyParticipant = buildParticipant(hmilyTransactionContext, hmily, method, clazz, arguments, args); if (hmilyTransactionContext.getRole() == HmilyRoleEnum.INLINE.getCode()) { hmilyTransactionExecutor.registerByNested(hmilyTransactionContext.getTransId(), hmilyParticipant); } else { hmilyTransactionExecutor.enlistParticipant(hmilyParticipant);