0

我有一个使用容器管理持久性的 JSF/EJB/JPA 应用程序。在一种情况下,通过 HTTP 对外部服务进行调用是有成本的,该成本被分配回请求用户。在当前实现中,发出 HTTP 请求的过程由在后台定期运行的 EJB 计时器方法执行。

计时器方法可能必须在一次调用中处理多个请求,尽管每个请求都需要独立处理,独立于将成本分配给用户,也就是说。如果用户 A 没有足够的信用来购买一本书,这不能阻止用户 B 成功购买一本书,导致他们的余额由于回滚而被借记。

为了为每个请求的独立处理提供对事务分界的控制,我将 bean 管理的事务用于计时器方法所在的类。这是我现在所拥有的 java 伪代码版本:

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class MessageTimer {
  private void processMessages(UserMessage msg) {
    tx.begin();
    em.joinTransaction();

    try {
      userData = em.find(..., PESSIMISTIC_WRITE);

      if(user has enough credit) {
        debit cost from user;

        status = make external http request to order book from supplier;
        if(status == success) {
          commit = true;
        }
      }
    } catch(Exception) {
      tx.rollback();
    }

    if(commit) {
      tx.commit();
    }
    else {
      tx.rollback();
    }
  }
}

所以我的想法是我开始一个事务,假设成功并从用户那里扣除成本,调用 http 服务并在它成功时提交,否则回滚。

我有一种不安的感觉,即我可能无法使用这种设计,特别是在 pessimistic_write 事务中有冗长的 http 调用(实际上是使用 jax-rs 完成的)。我想知道我是否可以首先在交易中借记用户(开始/借记/提交),进行 http 调用,然后在发生任何错误时记入用户,但没有交易完整性。

这对我来说是新的领域,谁能指出我正确的方向,有没有一种既定的方式来做我想做的事情?

非常感谢。

ps 我正在使用带有 Seam 3 的 glassfish 3.1 堆栈

4

1 回答 1

0

我不确定 jax-rs 通信层如何。如果通信是单线程的,那么您编写的代码是一个长时间运行的事务。这可能会使您的应用程序变慢。

我不是技术大师,但我可以建议的是 -

记入帐户并在线程上调用 jax-rs。在这种情况下,事务将在向远程节点发送调用之前关闭。并且它不会是一个长时间运行的事务,因此应用程序会更快。

于 2011-05-27T04:26:11.390 回答