2009-09-04 6 views
0

私は状況を説明しようとします。私たちにはウェブサービスがあります。各リクエストでWebサービスがJTAトランザクションを開始します。その中のXAデータソースを通じていくつかのデータベース呼び出しを実行し、他のいくつかのWebサービス(トランザクションコンテキスト外)を呼び出し、他のサーバー上でいくつかのリモートEJB呼び出しを行います。トランザクション内でトランザクションレスEJBコールを作成する

問題は、コンテナがEJBをトランザクションに関与させようとしているように見えますが、論理的に見えますが、実際にはそのトランザクションに参加していないときは、最終的なコミット段階ですが、EJBコールを除外すると正常に動作します。

EJB実装を変更できず、Webサービスコードのみを制御できません。ですから、私の質問は、トランザクション認識型EJBへのEJB呼び出しをどのようにして行うのですか?しかし、JTAトランザクションから、他のXAリソースのためのJTAトランザクションにはまだありますか?私は私の質問を明確にしたいと思う。

EDIT:擬似コードの例と、それがより明確にしようとすると:

// Begin transaction 
UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION); 
tx.begin(); 

// Do some database operations on XA datasource 

// Call remote EJB which has transcation attribute set to 'Supports' 
AccountInfo account = accountEjb.getAccountInfo(userId, accountId); // <-- Is it possible to make this to be not be part of user transction? 

// Do some more database operations on XA datasource 

// Commit transaction 
tx.commit(); 
+0

なぜあなたはタイムアウトを増やしませんか? –

+0

問題がタイムアウトしていないため、すべてのコールがミリ秒以内に正常に終了しますが、トランザクションが最後にコミットされるとタイムアウトします。ejbコールがコールシーケンスから削除されると、okをコミットします。だから、実際にはサーバ間の通信で何かをしなければならないと思っていますが、タイムアウトの価値はありません。 –

答えて

2

適切なトランザクション属性を使用して別のBeanを作成できます。このBeanは、すべての呼び出しを最初のBeanに委譲できます。

また、別のスレッドからこのejbを呼び出すこともできます。

+0

私は別のスレッドを使用しようとします。 –

1

EJBのトランザクションは、宣言です:指定されたEJBの特定の展開のために、あなたはそのトランザクションセマンティクスを指定します。厳密なEJBは(もちろん別の名前で)デプロイすることができ、そのデプロイメントにはさまざまな要件を指定できます。これは、(a)あなたが少なくともejbのjarを持っていること、(b)問題のejbが単独であり、他のコンポーネントに依存していないこと、(c)ejb hasnの開発者宣言的なトランザクションの考え方に違反していて、彼のBeanはトランザクションコンテキストの外でも動作しています。

+0

私はEJBを制御できませんが、そのトランザクション属性が "サポート"に設定されていることを知っています。また、そのEJBへのスタンドアロン(コンテナからの)呼び出しも問題なく行いました。また、EJBと私のWebサービスは異なるサーバーに配備されており、変更することもできません。 –

+0

それで、それは不可能ですか? –

0

あなたは、適切なTX属性を持つ別のメソッドを作成し、自己注射したプロキシ(擬似コード)を介して、それを呼び出すことができます。

@Stateless 
public class LocalEJB1 { 

    @EJB 
    private LocalEJB1 localEJB1; 

    @EJB 
    private AccountEJB accountEjb; 

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
    public AccountInfo callNonTx() { 
     return accountEjb.getAccountInfo(userId, accountId); 
    } 

    public void yourCurrentMethod() { 
     // Begin transaction 
     UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION); 
     tx.begin(); 

     AccountInfo account = localEJB1.callNonTx(); 
     // Do some more database operations on XA datasource 

     // Commit transaction 
     tx.commit(); 
    } 
} 
関連する問題