2017-07-06 15 views
0

JMS用のプログラムによるトランザクション管理を持つリファクタリングが必要な古いコードがあります。Spring JMS - 注釈を使用した宣言的トランザクション管理

JMSを使用してすべてのメッセージを同期的に読み取り、一度に1つずつ処理するスケジュールされたサービスがあります。私は取引のためにJmsTransactionManagerを使用しています。このコードが動作することを

//code from scheduled service's run method 
private void run() 
{ 
    javax.jms.Message jmsMessage = null; 
    do 
    { 
     TransactionStatus status = null; 
     try 
     { 
      status = jmsTransactionManager.getTransaction(new DefaultTransactionDefinition()); 
      jmsMessage = jmsTemplate.receive(heldTransmissionDestination); 
      if(jmsMessage != null) 
      { 

       process(jmsMessage); 
       jmsMessage.acknowledge(); //session is still open within the transaction 
      } 
      jmsTransactionManager.commit(status); 
     } 
     catch(Exception e) 
     { 
      logger.error("Exception: ", e); 
      if(status != null) 
      { 
       jmsTransactionManager.rollback(status); 
       logger.info("JMSTransaction rollback successful"); 
      } 
      //since an exception occured, break out of the do-while 
      break; 
     } 
    } 
    while(jmsMessage != null); 
} 

注:私はメッセージごとに私のトランザクションを管理するために、アノテーションを使用しての代わりに、そのようにプログラム的にそれらを管理する宣言的トランザクション管理を使用することができます。 jmsTemplateのための構成は以下のように、trueに設定さsessionTrasactedました:

// from config 
@Bean 
public JmsTemplate jmsTemplate() { 
    JmsTemplate jmsTemplate = new JmsTemplate(); 
    jmsTemplate.setSessionTransacted(true); 
    // ... other stuff ommited for brevity 
    return jmsTemplate; 
} 

答えて

1

を、私はそれを試してみましたし、それが注釈で動作ありません。しかし、いくつかの注意事項:

@Configuration 
@EnableTransactionManagement 
public class JmsConfig { 

    @Bean 
    public JmsTemplate jmsTemplate() { 
     JmsTemplate jmsTemplate = new JmsTemplate(); 
     jmsTemplate.setSessionTransacted(true); 
     // ... other stuff ommited for brevity 
     return jmsTemplate; 
    } 

    @Bean 
    public JmsTransactionManager jmsTransactionManager() { 
     JmsTransactionManager jmsTransactionManager = new JmsTransactionManager(); 
     jmsTransactionManager.setConnectionFactory(jmsConnectionFactory()); 
     return jmsTransactionManager; 
    } 

    //other bean definitions omitted for brevity 
} 

はまた、あなたのXMLでこのような何かを行うことができます:

まず、そのようなあなたの構成で@EnableTransactionManagementの使用(あなたは純粋なJavaのDSLを使用している場合)であります代わりに、上記の構成:

<tx:annotation-driven transaction-manager="jmsTransactionManager"/> 
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager"> 
    <property name="connectionFactory"> 
     <ref bean="jmsConnectionFactory" /> 
    </property> 
</bean> 

第二は、トランザクションがproxied(AOP)である方法です。このため、トランザクション内にある必要があるロジックは、プロキシできるように別のクラスに移動する必要がありました。 transactionManagerだけを指定した場合、springはトランザクションマネージャを自動的に検出します。しかし私の場合、私はそのような複数の豆を持っているので、私はこれを明示的に使用しなければなりませんでした。私のアノテーションのvalue属性でそれを参照してください:

public class ServiceToSchedule 
{ 

    @Autowired 
    private JmsMessageProcessor jmsMessageProcessor; 

    public void run() 
    { 
     Message jmsMessage = null; 

     do 
     { 
      try { 
       jmsMessage = jmsMessageProcessor.readAndProcessMessage(); 
      } catch (JMSException e) { 
       logger.debug("JMSException processing heldTransmission: ", e); 
       break; 
      } catch (Exception e) { 
       logger.debug("Exception processing heldTransmission: ", e); 
       break; 
      } 

     } 
     while(jmsMessage != null); 
    } 
} 

public class JmsMessageProcessor 
{ 

    @Transactional(value="jmsTransactionManager", propagation = Propagation.REQUIRES_NEW) 
    public Message readAndProcessMessage() throws JMSException 
    { 
     Message jmsMessage = jmsTemplate.receive(heldTransmissionDestination); 
     if(jmsMessage != null) 
     { 
      process(jmsMessage); 
     } 
     //have to return to break out of the while in the caller 
     return jmsMessage; 
    } 

    @Transactional(value="jmsTransactionManager", propagation = Propagation.NESTED) 
    protected void process(Message jmsMessage) 
    { 
     //code to process the jmsMessage, can potentially throw 
     //an exception that requires rolling back the jms transaction 
    } 
} 
関連する問題