我有一个使用容器管理持久性的 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 堆栈