2011-05-26 139 views
0

我有一個使用容器管理持久性的JSF/EJB/JPA應用程序。有一種情況是通過HTTP向外部服務發起呼叫,其中有一個費用,這個費用被分配回請求用戶。在當前實現中,通過在後臺定期運行 的EJB定時器方法執行進行HTTP請求的過程。在JPA/JTA事務中調用HTTP服務 - 事務完整性

計時器方法可能不得不在一次調用中處理多個請求,但每個請求需要獨立處理,獨立於將 成本分配給用戶,也就是說。如果用戶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服務和如果成功則返回,否則返回。

我有一種不安的感覺,我可能不會在任何地方大致正確附近這種 設計,尤其是具有內部 冗長的HTTP調用(使用JAX-RS實際完成)的pessimistic_write交易。我想知道是否可以首先在交易 借記用戶(開始/借記/提交),進行http呼叫,然後在發生任何錯誤 時扣除用戶,但沒有交易完整性。

對我來說,這是一個新的領域,任何人都可以指出我正確的方向,有沒有一個 做我想做的事情?

很多謝謝。

p.s.我正在使用Seam 3的glassfish 3.1堆棧

回答

0

我不知道jax-rs通信層是如何的。如果通信是單線程的,那麼你寫的代碼是一個長時間運行的事務。這可能會讓你的應用程序變慢。

我不是一個技術大師,但我可以建議是 -

信用賬戶,使JAX-RS調用一個線程。在這種情況下,在將呼叫發送到遠程節點之前,交易將被關閉。它不會是一個長時間運行的事務,所以應用程序會更快。

+0

嗨,我在EJB容器中運行,所以不能使用我認爲的線程。我需要http調用的結果來確定是否發生了成本,所以我不確定我有什麼選項。這是一個長期運行的交易,當然,但我沒有看到它的方式。 – Oversteer 2011-05-28 11:37:49