2017-11-19 5 views
2

Ich habe einen Spring-Integrationsfluss, der ActiveMQ mit OracleAQ verbindet. Siehe Beispielprojekt unter GitHub - https://github.com/cknzl2014/springio-ora-xa/tree/atomikos.Langsame Leistung spring.io-Fluss von ActiveMQ nach OracleAQ mit XA

Wenn ich es ohne XA laufen lasse, ist es blitzschnell. Mit XA verarbeitet es nur 1 bis 2 Nachrichten pro Sekunde. Beim Profiling der Anwendung sehe ich, dass für jede Nachricht eine neue physische Verbindung hergestellt wird, und damit die Metadaten-Abfrage auf der Oracle-Datenbank ausgegeben wird. Aber ich verstehe nicht, warum es das tut und wie ich das verhindern kann.

Hat jemand von euch Erfahrung mit OracleAQ und XA? Könnte dies ein Problem mit dem XA-Transaktionsmanager sein (Ich benutze Atomikos)?

Danke für Ihre Hilfe, Chris

Antwort

0

Zunächst einmal sollten Sie sicher sein, dass Sie pool für JDBC-Verbindungen verwenden.

Auf der anderen Seite können Sie ChainedTransactionManager anstelle von XA für zwei Ziel-Transaktionsmanager verwenden - JMS and JDBC. Weitere Informationen finden Sie im Projekt JDBC extensions.

Es gibt auch einige Oracle AQ API in diesem Projekt.

+0

Ich lese die [JMS und JDBC] (https://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-witound-xa.html) Artikel. Sehr interessant. Besonders mag ich das _Best Efforts 1 PC_ Muster, das viel schneller sein wird, aber idempotente Empfänger benötigt. –

1

Wir haben eine Lösung für das Problem gefunden. Es besteht aus vier Schritten.

Schritt 1: Verwenden Sie die neuesten Bibliotheken Oracle-Client
Der erste Schritt ist die neueste Oracle 12c Client-Bibliotheken zu verwenden. Es gab signifikante Verbesserungen in der ojdbc8.jar, z.B. Sie verwenden gespeicherte Prozeduren, um die Metadaten jetzt zu erhalten.
Dies erhöhte den Durchsatz auf etwa 10 msgs/s.

Schritt 2: Bündelung Setup-Verbindung
korrekt Der zweite Schritt nach Art der Verbindung Pooling wurde die Verbesserung der http://thinkfunctional.blogspot.ch/2012/05/atomikos-and-oracle-aq-pooling-problem.html:

<bean id="oraXaDataSource" primary="true" 
    class="oracle.jdbc.xa.client.OracleXADataSource" destroy-method="close"> 
    <property name="URL" value="${oracle.url}" /> 
    <property name="user" value="${oracle.username}" /> 
    <property name="password" value="${oracle.password}" /> 
</bean> 

<bean id="atomikosOraclaDataSource" 
    class="org.springframework.boot.jta.atomikos.AtomikosDataSourceBean"> 
    <property name="uniqueResourceName" value="xaOracleAQ" /> 
    <property name="xaDataSource" ref="oraXaDataSource" /> 
    <property name="poolSize" value="5" /> 
</bean> 

<bean id="OracleAQConnectionFactory" class="oracle.jms.AQjmsFactory" factory-method="getConnectionFactory"> 
    <constructor-arg ref="atomikosOraclaDataSource" /> 
</bean> 

Diese Konfiguration allein resultet in Ausnahmen aufgrund der 'Auto-commit' der Oracle-Verbindung.

Schritt 3: autoCommit auf false
Der dritte Schritt war die folgende Java-Systemeigenschaft zu setzen (siehe https://docs.oracle.com/database/121/JAJDB/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_AUTOCOMMIT):

-DautoCommit=false 

Aber dann/der Durchsatz ging auf 1 bis 2 msg s wieder.

Schritt 4: oracle.jdbc festlegen.autoCommitSpecCompliant auf false
Der letzte Schritt war die folgende Java-Systemeigenschaft zu setzen (siehe https://docs.oracle.com/database/121/JAJDB/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_AUTO_COMMIT_SPEC_COMPLIANT):

-Doracle.jdbc.autoCommitSpecCompliant=false 

Jetzt bekommen wir einen Durchsatz von 80 msgs/s.

Fazit
Die Einstellung von oracle.jdbc.autoCommitSpecCompliant auf false ist nicht elegant, aber das Problem gelöst. Wir müssen weiter untersuchen, um zu sehen, wie wir dieses Problem umgehen können, ohne oracle.jdbc.autoCommitSpecCompliant auf false zu setzen.

Vielen Dank an Dani Steinmann (stonie) für die Hilfe!

S.S .: Ich habe das Beispielprojekt unter GitHub - https://github.com/cknzl2014/springio-ora-xa/tree/atomikos aktualisiert.