gpt4 book ai didi

java - ATG:更新订单模式

转载 作者:太空宇宙 更新时间:2023-11-04 12:33:37 27 4
gpt4 key购买 nike

众所周知,您必须使用以下模式才能更新 ATG Form-Handlers 中不继承自 PurchaseProcessFormHanlder 的订单:

boolean acquireLock = false;
ClientLockManager lockManager = getLocalLockManager();

try {
acquireLock = !lockManager.hasWriteLock(profile.getRepositoryId(), Thread.currentThread());
if (acquireLock) {
lockManager.acquireWriteLock(profile.getRepositoryId(), Thread.currentThread());
}

boolean shouldRollback = false;

TransactionDemarcation transactionDemarcation = new TransactionDemarcation();
TransactionManager transactionManager = getTransactionManager();

transactionDemarcation.begin(transactionManager, TransactionDemarcation.REQUIRED);

try {
synchronized (getOrder()) {
...
...
...
}
} catch (final Exception ex) {
shouldRollback = true;
vlogError(ce, "There has been an exception during processing of order: {0}", getOrder().getId());
} finally {
try {
transactionDemarcation.end(shouldRollback);
} catch (final TransactionDemarcationException tde) {
vlogError(tde, "TransactionDemarcationException during finally: {0}", tde.getMessage());
} finally {
vlogDebug("Ending Transaction for orderId: {0}", order.getId());
}
}
} catch (final DeadlockException de) {
vlogError(de, "There has been an exception during processing of order: {0}", order.getId());
} catch (final TransactionDemarcationException tde) {
vlogError(tde, "There has been an exception during processing of order: {0}", order.getId());
} finally {
try {
if (acquireLock) {
lockManager.releaseWriteLock(getOrder().getProfileId(), Thread.currentThread(), true);
}
} catch (final Throwable th) {
vlogError(th, "There has been an error during release of write lock: {0}", th.getMessage());
}
}

理论上,任何继承自 PurchaseProcessFormHandlerFormHandler 都已实现以下步骤 OOTB:

  1. 获取LocalLockManager以避免并发线程修改相同的顺序:

    try {
    acquireLock = !lockManager.hasWriteLock(profile.getRepositoryId(), Thread.currentThread());
    if (acquireLock) {
    lockManager.acquireWriteLock(profile.getRepositoryId(), Thread.currentThread());
    }
    } catch (final DeadlockException de) {
    vlogError(de, "There has been an exception during processing of order: {0}", order.getId());
    }
  2. 创建新的交易:

    try {
    TransactionDemarcation transactionDemarcation = new TransactionDemarcation();
    TransactionManager transactionManager = getTransactionManager();

    transactionDemarcation.begin(transactionManager, TransactionDemarcation.REQUIRED);
    } catch (final TransactionDemarcationException tde) {
    vlogError(tde, "There has been an exception during processing of order: {0}", order.getId());
    }
  3. 结束正在使用的事务:

    try {
    TransactionManager transactionManager = getTransactionManager();
    Transaction transaction = transactionManager.getTransaction();

    // If transaction is elegible for commiting:
    transactionManager.commit();
    transaction.commit();

    // otherwise
    transactionManager.rollback();
    transaction.rollback();
    } catch (final Exception ex) {
    error = true;
    vlogError(ex, "There has been an exception during processing of order: {0}", order.getId());
    } finally {
    // handle the error
    }
  4. 释放用于事务的锁:

    finally {
    ClientLockManager lockManager = getLocalLockManager();
    lockManager.releaseWriteLock(profile.getRepositoryId(), Thread.currentThread(), true);
    }

根据 ATG 文档,以下方法实现上述行为:

  1. 方法:beforeSet

    Called before any setX methods on this form are set when a form that modifies properties of this form handler is submitted. Creates a transaction if necessary at the beginning of the form submission process, optionally obtaining a local lock to prevent multiple forms from creating transactions that may modify the same order.

    • 步骤:1 和 2
  2. 方法:afterSet

    Called after any setX methods on this form are set when a form that modifies properties of this form handler is submitted. Commits or rolls back any transaction created in beforeSet, and releases any lock that was acquired at the time.

    • 步骤:3 和 4

例如您只需办理以下手续即可更新订单:

  1. 同步将用于订单更新的代码块,以避免线程并发。

    synchronized (getOrder()) {
    ...
    ...
    ...
    }
  2. 执行订单修改:

    synchronized (getOrder()) {
    getOrder().setXXX();
    getOrder().removeXXX();
    }
  3. 更新订单(将调用updateOrder管道链):

    synchronized (getOrder()) {
    ...
    ...
    ...
    getOrderManager().updateOrder(order);
    }

这非常简单,除非您必须在以下任何情况下编辑订单:

  • 不在 PurchaseProcessFormHandler 层次结构中的表单处理程序或自定义表单处理程序。
  • 帮助程序或工具类。
  • 处理器
  • ATG REST 网络服务
  • &c

如果是这样,您将必须在组件中实现事务模式

问题!

  • 除了事务模式之外,还有其他已知的模式可以使用吗?
  • 是否可以像 ATG 在 PurchaseProcessFormHandler 中那样实现/覆盖 FormHandler 中的 beforeSetafterSet 方法
  • 您还知道其他方法吗?

最佳答案

您上面概述的一系列步骤是更新订单的规定步骤系列。

请随意以任何您认为有用的方式将其分解出来。只需确保当您更新订单时,您或您继承的代码已执行必要的步骤。

ATG 进行类似因式分解的一种常见方法是,对于给定方法,例如 X(...),您将拥有 preX(...)doX(...)postX(...) 方法。您可以使用 preX()postX() 方法中的所有样板代码创建一个抽象类,甚至可以声明为最终类,并将 doX() 声明为抽象类。然后,您的组件将从抽象类继承,并且必须实现 doX() 方法。您可能还需要显式处理异常。

本质上,这就是标准表单处理程序所做的事情(以不同的名称)。

例如;

public final void X(...) {
preX(...); // call the pre method

try {
doX(...); // call the do method
} catch (XException xe) {
// handle error
}

postX(...); // call the post method
}

protected final void preX(...) {
// do everything you need to do before your customer code
}

protected final void postX(...) {
// do everything you need to do after your customer code
}

protected abstract void doX(...) throws XException;

您可以做的另一件事是定义一个包含所有样板代码的注释,而不是从抽象类继承。

您可以用类似的方式做的第三件事,但很难硬塞进 ATG 代码中,可能是使用第三方框架定义一个方面或方法调用拦截器。

但是,再次强调,无论您做什么、如何做,只要确保遵循所有步骤即可。

关于java - ATG:更新订单模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37580167/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com