1

私はSpring Integration 4.1.5を使用していて、トランザクションで何かをしようとしていますが、残念ながら実際の例は見つかりませんでした。メッセージを探しているJMSポーラーをセットアップしようとしています。メッセージが受信されると、サービスアクティベータは行をデータベースに挿入し、メッセージは別のサービスアクティベータに渡されます。私は最初の2つの部分を作りたいと思います、メッセージピックアップ&データベース挿入トランザクション。私は残りの流れをトランザクション的にしたくありません。 Weblogicをアプリケーションコンテナとして使用しているので、WebLogicJtaTransactionManagerを使用しています。JMS Poller Transactional

私が取り組んでいる問題は、最初の2つの部分をトランザクションにすることができないことです。それはすべてか何もない。私は多くの方法を試しましたが、ポーラーのアドバイスチェーンを使うのが最善の策だと感じています。私はどのメソッドがトランザクションの一部であるかを制御することができます。

メッセージ駆動型のリスナーを使用した例を見てきましたが、私はWeblogicを使用しており、Work Managerを使用していました。私は仕事マネージャーを利用するためにポーラーを使用する必要があると思います私はそれが未来のためのもう一つの質問だと思う)。

私はxmlを使って単純化しましたが、パッケージ名を編集するだけでなく、文脈によって問題が生じます。

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" 
    xmlns:file="http://www.springframework.org/schema/integration/file" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp" 
    xmlns:int-xml="http://www.springframework.org/schema/integration/xml" 
    xmlns:int-jms="http://www.springframework.org/schema/integration/jms" 
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/integration 
    http://www.springframework.org/schema/integration/spring-integration.xsd 
    http://www.springframework.org/schema/integration/file 
    http://www.springframework.org/schema/integration/file/spring-integration-file.xsd 
    http://www.springframework.org/schema/integration/sftp 
    http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd 
    http://www.springframework.org/schema/integration/xml 
    http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd 
    http://www.springframework.org/schema/integration/jms 
    http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd"> 


    <bean id="jtaTransactionManager" 
     class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"> 
     <property name="transactionManagerName" value="javax.transaction.TransactionManager" /> 
    </bean> 

    <bean id="insertMessageToDb" class="com.ReadMsgFromAxway" /> 
    <bean id="serviceActivator" class="com.CreateTMDFile" /> 

    <int-jms:inbound-channel-adapter id="jmsDefaultReceiver" 
     connection-factory="inboundDefaultAdaptorConnectionFactory" 
     extract-payload="false" destination="inboundAdaptorDefaultListenerQueue" 
     channel="inboundJMS" acknowledge="transacted"> 
     <int:poller id="poller" 
      max-messages-per-poll="100" fixed-rate="10"> 
      <int:advice-chain> 
       <ref bean="txAdvice" /> 
      </int:advice-chain> 
     </int:poller> 
    </int-jms:inbound-channel-adapter> 


    <tx:advice id="txAdvice" transaction-manager="jtaTransactionManager"> 
     <tx:attributes> 
      <tx:method name="processMessage" propagation="REQUIRED"/> 
     </tx:attributes> 
    </tx:advice> 

    <aop:config> 
     <aop:pointcut id="txOperation" 
      expression="execution(* axway.ReadMsgFromAxway.processMessage(..))"/> 
     <aop:advisor advice-ref="txAdvice" pointcut-ref="txOperation" /> 
    </aop:config> 

    <int:service-activator input-channel="inboundJMS" 
     output-channel="serviceActivatorChannel" ref="insertMessageToDb" method="processMessage" /> 

    <int:chain input-channel="serviceActivatorChannel" output-channel="nullChannel"> 
     <int:service-activator ref="serviceActivator" /> 
    </int:chain> 

</beans> 

ReadMsgFromAxway.java

public Message<File> processMessage(Message<?> message) { 
//Insert into DB 
     trackerProcess.insertUpdateMessageTracker(message, "axwayChannel", 
       "axwayChannel", currentStatusID, null, null); 
     count++; 
     int mod = count % 2; 
     if (mod != 0) { 
      // pass every 2 
      String hello = "hey"; 
     } else { 
      throw new RuntimeException("Testing transactional"); 
     } 

     Message<File> springMessage = MessageBuilder.createMessage(payloadFile, 
       messageHeaders); 
     return springMessage; 
    } 

XMLをそのまま実行時例外がスローされるか、または例外が次のサービス活性化剤成分で投げているかどうか、何もしません。

私はアドバイスは

 <tx:method name="*" propagation="REQUIRED"/> 

に属性を変更する場合は、第一の例外と第二サービス活性化剤は、ロールバックが発生します。私はこれが

 <tx:method name="processMessage" propagation="REQUIRED"/> 
     <tx:method name="*" propagation="NEVER"/> 

そして、第一のサービスの活性化因子、または第二アクチベーターで実行時例外がスローされているかどうか、メッセージがロールバックされます行う場合は奇妙なこと

。私はpointcutがトランザクションを引き起こすクラスを制限すると思いますが、多分私は何かを誤解しています。

もう1つのメモ - このアプリケーションは、いくつかの他の戦争を含む耳のファイルに格納されています。このコンテキストは、インバウンド・プロセス全体を開始し、ビジネス・ロジックを含む別のwarにJMSキューを介して接続します。メソッド名= "*"を使用するシナリオでは、ビジネスロジック戦争の例外を見て、元のインバウンドメッセージのJMSメッセージがロールバックされるようにしました。私は第二戦は、それがキュー経由でメッセージを受信するので、別のスレッドでその処理を行うため、トランザクションの一部ではないでしょう印象の下にありました。これはコンテナ管理されているJTAの副作用でしょうか?

ありがとうございます!

答えて

0

私はデイブSyerのarticle取引について、そこにあなたは「このような詳細」のリンクを見つけることができますあなたが読むことをお勧めします。

今は、トランザクションとAOPをまったく理解していないようです。 Spring FrameworkでAOPサポートにもっと注意を払う必要があります。

一般的に、宣言型トランザクション(メソッド上の@Transactional)は、AOPアドバイスの特別なケースです。 AOPの背後にある主なコンセプトは、アドバイスを指定するメソッド呼び出しによって生成されるコールスタック境界です。

しかし、ターゲットオブジェクトにそのようなメソッドがない場合、それはアドバイスされずにAOPプロキシにラップされます。あなたのケースではprocessMessageの場合と同様に、のJmsDestinationPollingSourceの契約として、org.springframework.messaging.Message.MessageSourceの周りの一部の内部オブジェクトにtxAdviceを適用します。

代わりに<transactional><poller>の設定を使用できます。そして、右:すべての流れは取引によってカバーされます。

は、その内部周り

Callable<Boolean> pollingTask = new Callable<Boolean>() { 

     @Override 
     public Boolean call() throws Exception { 
      return doPoll(); 
     } 
    }; 

handleMessage()ため、この場合に、トランザクションを終了するには、あなただけの通常の@Transactional場合と同様に、メソッド呼び出しを完了する必要があります。この目的のために、次のメッセージ処理を別のスレッドに委ねるべきです。デフォルトでは、すべて<channel>DirectChannelであり、現在の呼び出しスタックと結びついているからです。

この目的で、serviceActivatorChannelにはExecutorChannel<int:dispatcher task-executor="threadPoolExecutor"/>)を使用することができます。

そこから、残りのAOP設定は必要ありません。

他のウェブアプリの2番目の質問については不明です。あなたの側からの矛盾があった場合に、その作業を取り消すための論理があるように見えます。しかし、とにかくそれは別の質問のように見えます。

+0

お返事ありがとうございます@ Artem-bilan。私はを使って振り返り、それを動作させました。いくつかのドキュメントを見て、私はWeblogicの私のデータソースで2 Phase Commitを有効にする必要がありました。 –

+0

私はコメントをあまりにも早く提出し、十分に速く編集していませんでした...テストや、あなたが提案しているように、ポーラーのトランザクションを作成したりプロパゲートしたりすることはありませんか?私はを置き、トランザクションがないというエラーを受け取りました。ありがとう。 –

+0

??? 'MANDATORY'は新しいトランザクションを作成しません。 'TransactionDefinition'でそのJavaDocを見てください。ほとんどの場合、デフォルトのものを 'REQUIRED'だけ使用してください。反対側からは ''に 'txAdvice'は必要ありません。 ''があります。 –