Я пытаюсь заставить транзакции XA работать на сервере TomEE для БД Oracle. Использование менеджера транзакций AtomikOS через конфигурацию Spring.
Я использовал пример из документации по atomikos https://www.atomikos.com/Documentation/SpringIntegration
При запуске сервера я вижу ниже исключение, в результате чего пул соединений xa не создан.
SEVERE: Unable to create initial connections of pool.
java.sql.SQLException: oracle.jdbc.xa.client.OracleXADataSource cannot be cast to java.sql.Driver
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:254)
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:710)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:644)
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:466)
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:143)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:554)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:242)
at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:141)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:842)
at org.apache.naming.NamingContext.lookup(NamingContext.java:167)
at org.apache.tomee.catalina.OpenEJBNamingContextListener.bindResource(OpenEJBNamingContextListener.java:266)
at org.apache.tomee.catalina.OpenEJBNamingContextListener.addResource(OpenEJBNamingContextListener.java:256)
at org.apache.tomee.catalina.OpenEJBNamingContextListener.processInitialNamingResources(OpenEJBNamingContextListener.java:223)
at org.apache.tomee.catalina.OpenEJBNamingContextListener.start(OpenEJBNamingContextListener.java:92)
at org.apache.tomee.catalina.OpenEJBNamingContextListener.lifecycleEvent(OpenEJBNamingContextListener.java:74)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:394)
at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:339)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:731)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.startup.Catalina.start(Catalina.java:693)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:428)
Caused by: java.lang.ClassCastException: oracle.jdbc.xa.client.OracleXADataSource cannot be cast to java.sql.Driver
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:246)
... 31 more
Конфигурация источника данных и Spring bean, как показано ниже.
<Resource
name="xads"
auth="Container"
type="javax.sql.XADataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="oracle.jdbc.xa.client.OracleXADataSource"
url="url"
username="user"
password="password"
accessToUnderlyingConnectionAllowed="true"
maxTotal="10"
maxIdle="1"
maxWaitMillis="10000"
testWhileIdle="true"
validationQuery="select 1 from dual"
/>
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
Я также пытался изменить
driverClassName = "oracle.jdbc.xa.client.OracleXADataSource"
в
driverClassName = "oracle.jdbc.OracleDriver", но тогда транзакции фактически не присоединяются.
Я видел аналогичное сообщение в https://grokbase.com/t/tomcat/users/117czb4yf0/tomcat-pool-and-xa-datasource, но предлагаемый блог (http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency) для устранения проблемы больше не действителен и перенаправляет на https://tomcat.apache.org/
Я ожидаю, что источник данных xa присоединится к другим транзакциям и выполнит двустороннюю фиксацию.