I recently changed from using Spring's local transactions to Jencks'
JTA transactions and I've run into a problem where the number of
database connections that are open explodes as my unit and
integration tests run. I made the change because I'm using both JDO
and JCA (Apache's Jackrabbit) in my project, and I'd like them to
participate in the same transaction, while still running in Tomcat
5.5. I've tried changing the settings for the pooling and thread/
transaction caching, but nothing has worked yet.
My integration tests are set up in some 15 files, with each file
having anywhere from 1 to more than 20 tests. Some files have a setup
and teardown process that requires transactions to put data into the
JDO or JCA store (to test queries); in many cases, two transactions
are used both setup and tear down, plus a separate transaction for
the actual test. By the time my unit tests finish, I'm seeing more
than 50 open connections to PostgreSQL (based on the number of
postgresql processes running). In some build situations (such as
generating the maven site), I'm running out of database connections
(the unit tests are run twice) which causes the tests to lock until a
connection becomes available (occasionally maven crashes with a bus
error at this point). When maven exits, all the connections are closed.
I've included the configuration I'm using below. You can see that
both JDO and Jackrabbit are configured to use Spring's
JtaTransactionManager, which in turn is configured to use Jencks'
GeronimoTransactionManagerFactoryBean and TransactionManagerFactoryBean.
If anyone could point me in the right direction on this, I'd really
appreciate it. Also, if Jecnks isn't the best way to accomplish this,
and it would be better in this case for me to use a full app server
like JBoss or Geronimo, that'd be good to know too.
Thanks,
Mark
<bean id="connectionTracker"
class="org.apache.geronimo.connector.outbound.connectiontracking.Connect
ionTrackingCoordinator"
/>
<bean id="transactionContextInitializer"
class="org.jencks.interceptor.TransactionContextInitializer">
<property name="associator">
<ref local="connectionTracker" />
</property>
</bean>
<bean id="transactionManagerImplementation"
class="org.jencks.factory.TransactionManagerFactoryBean">
<property name="defaultTransactionTimeoutSeconds">
<value>600</value>
</property>
<property name="transactionLog">
<bean
class="org.apache.geronimo.transaction.log.UnrecoverableLog" />
</property>
</bean>
<bean id="transactionContextManager"
class="org.jencks.factory.TransactionContextManagerFactoryBean">
<property name="transactionManager">
<ref local="transactionManagerImplementation" />
</property>
</bean>
<bean id="userTransaction"
class="org.jencks.factory.GeronimoTransactionManagerFactoryBean">
<property name="transactionContextManager">
<ref local="transactionContextManager" />
</property>
</bean>
<!-- The global transaction manager -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction">
<ref local="userTransaction" />
</property>
<property name="transactionManager">
<ref local="transactionManagerImplementation" />
</property>
</bean>
<bean id="transactionSupport"
class="org.jencks.factory.XATransactionFactoryBean">
<property name="useTransactionCaching">
<value>true</value>
</property>
<property name="useThreadCaching">
<value>true</value>
</property>
</bean>
<bean id="poolingSupport"
class="org.jencks.factory.SinglePoolFactoryBean">
<property name="maxSize">
<value>1</value>
</property>
<property name="minSize">
<value>1</value>
</property>
<property name="blockingTimeoutMilliseconds">
<value>60</value>
</property>
<property name="idleTimeoutMinutes">
<value>1</value>
</property>
<property name="matchOne">
<value>true</value>
</property>
<property name="matchAll">
<value>true</value>
</property>
<property name="selectOneAssumeMatch">
<value>true</value>
</property>
</bean>
<bean id="connectionManager"
class="org.jencks.factory.ConnectionManagerFactoryBean">
<property name="transactionSupport">
<ref local="transactionSupport" />
</property>
<property name="poolingSupport">
<ref local="poolingSupport" />
</property>
<property name="transactionContextManager">
<ref local="transactionContextManager" />
</property>
<property name="connectionTracker">
<ref local="connectionTracker" />
</property>
</bean>
<!-- Define the Persistance Manager Factory -->
<bean id="persistenceManagerFactoryTarget"
class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean">
<property name="configLocation">
<value>classpath:jdo.properties</value>
</property>
</bean>
<bean id="persistenceManagerFactory"
class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFac
toryProxy">
<property name="targetPersistenceManagerFactory">
<ref local="persistenceManagerFactoryTarget" />
</property>
<property name="allowCreate">
<value>false</value>
</property>
</bean>
<!-- The generic DAO Transaction Proxy bean. All DAO instances are
children of this bean. -->
<bean id="daoTransactionProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFacto
ryBean"
abstract="true">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="store*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- All DAO beans here -->
...
<!-- JCA (Jackrabbit) configuration -->
<bean id="repositoryManagedConnectionFactory"
class="org.apache.jackrabbit.jca.JCAManagedConnectionFactory">
<property name="homeDir">
<ref bean="repositoryDirectoryLocation" />
</property>
<property name="configFile">
<bean factory-bean="repositoryConfigurationResource" factory-
method="getPath" />
</property>
</bean>
<bean id="whisperContentRepository"
class="org.springframework.jca.support.LocalConnectionFactoryBean">
<property name="managedConnectionFactory">
<ref local="repositoryManagedConnectionFactory" />
</property>
<property name="connectionManager">
<ref bean="connectionManager" />
</property>
</bean>