2017-02-26 2 views
1

Wir müssen eine Nachricht von einer JMS-Warteschlange an eine Datenbank in einer Transaktion beibehalten, um sicherzustellen, dass die JMS-Nachricht nicht bestätigt wird, wenn während der DB ein Fehler auftritt. Basierend auf der hier- Transaction handling while using message driven channel adapter & service activator Im Folgenden bereitgestellte Lösung ist der Ansatz, den ich beiSynchronisieren von JMS-Nachrichtenwarteschlange und JDBC-Transaktion - Ist Transaktionsproxy erforderlich

angekommen
<int-jms:message-driven-channel-adapter id="jmsIn" 
    transaction-manager="transactionManager" 
    connection-factory="sConnectionFactory" 
    destination-name="emsQueue" 
    acknowledge="transacted" channel="jmsInChannel"/> 

<int:channel id=" jmsInChannel " /> 

<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> 
    <property name="url" value="jdbc:hsqldb:mem:testdb" /> 
</bean> 

<!-- Transaction manager for a datasource --> 
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
     <property name="dataSource" ref="dataSource" /> 
</bean> 

    <bean id="sconnectionFactory"  class="org.springframework.jms.connection.TransactionAwareConnectionFactoryProxy"> 
     <property name="targetConnectionFactory"> 
      <bean class="project.TestConnectionFactory"> 

      </bean> 
     </property> 
     <property name="synchedLocalTransactionAllowed" value="true" /> 
    </bean> 

Bitte bestätigen Sie, ob das Verständnis korrekt ist. Außerdem haben die folgenden Abfragen

  1. Ist das TransactionAwareConnectionFactoryProxy notwendig in diesem Szenario
  2. JMS Queue und JDBC sind zwei separate Transaktionsressourcen. Einspritzt jdbc Transaktionsmanager in JMS-Adapter wie in diesem Beispiel gleichwertig gezeigt, die eine ChainedTransactionManager (Verkettungs JMS Transaktion Mananger und JDBC-Transaktions-Manager) zu verwenden

Antwort

1

Für TransactionAwareConnectionFactoryProxy, bitte, fragen seine JavaDocs:

* Proxy for a target CCI {@link javax.resource.cci.ConnectionFactory}, adding 
* awareness of Spring-managed transactions. Similar to a transactional JNDI 
* ConnectionFactory as provided by a Java EE server. 
* 
* <p>Data access code that should remain unaware of Spring's data access support 
* can work with this proxy to seamlessly participate in Spring-managed transactions. 
* Note that the transaction manager, for example the {@link CciLocalTransactionManager}, 
* still needs to work with underlying ConnectionFactory, <i>not</i> with this proxy. 

Ich bin mir nicht sicher, wie das mit Ihrer Anfrage bezüglich der JMS + DB-Transaktion zusammenhängt, aber ich denke, Sie sollten sich Gedanken über den Transaktionsmanager machen, der beide transaktionalen Ressourcen unterstützt.

Zu diesem Zweck schlägt Spring JtaTransactionManager für XA-Transaktionen vor. Oder Sie können prüfen ChainedTransactionManager verwenden basierend auf dem Dave Syer Artikel: http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

UPDATE

Wenn lokale Transaktion für Sie in Ordnung sind, können Sie wirklich mit dem TransactionAwareConnectionFactoryProxy und seine synchedLocalTransactionAllowed zu true voran gehen. Und natürlich verwenden Sie das DataSourceTransactionManager direkt von der <int-jms:message-driven-channel-adapter>.

Ansonsten müssen Sie mit dem ChainedTransactionManager gehen. Diese Lösung fügt wirklich etwas Overhead über die erste TransactionAwareConnectionFactoryProxy-basierte hinzu.

+0

Ich ging durch Daves Artikel Best-JMS-DB-Projekt. Es injiziert eine DataSourceTransactionManager-Bean in jms: listener-container (Ich habe diesen transactionManager in den messagegesteuerten Kanaladapter injiziert, der auf dem Message Listener-Container basiert), verwendet aber keinen JmsTransactionManager. Ich kann keine explizite Verkettung in diesem Projekt oder JTA Transaction Manager sehen. Wie wird die JMS-Transaktionsressource und die JDBC-Transaktionsressource in diesem Beispiel synchronisiert? – vjm

+0

Bitte schauen Sie in meine UPDATE in der Antwort. –

+0

Danke, können Sie auch vorschlagen, den Unterschied zwischen den beiden Ansätze - ist die lokale Transaktion 1PC (so müssen doppelte Nachrichten behandeln), während ChainedTransactionManager 2PC – vjm