0

I have a project that uses Spring. In local environment I use Derby (with Jetty) that gives me the perfomance that I need in this environemnt (in production is used Oracle and Weblogic).

The problem is that I need new transactions in some specific operations. This specific operations use the annotation @Transactional(propagation=REQUIRES_NEW).

The problem is that with Derby when comes the time that a new transaction was supposed to be createad, the operation hangs and due time out. I tried to use H2 but in the same moment of creation of the new transaction, the database is restarted, meaning, the tables are dropped and are created again.

Derby and H2 don't support multiple transactions? I can't find anything that tells me the opposite.

My database configuration is:

<bean id="entityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    ...
    <property name="persistenceUnitName" value="ORACLE_PU"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
            <property name="showSql" value="true"/>
            <property name="generateDdl" value="true"/>
            <property name="databasePlatform" value="org.eclipse.persistence.platform.database.DerbyPlatform"/>
        </bean>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="shared-cache-mode">NONE</prop>
            <prop key="eclipselink.cache.shared.default">false</prop>
            <prop key="eclipselink.query-results-cache">false</prop>
            <prop key="eclipselink.weaving">false</prop>
            <prop key="eclipselink.ddl-generation">${oracle.eclipselink.ddl.generation}</prop>
            <prop key="eclipselink.ddl-generation.output-mode">database</prop>
            <prop key="eclipselink.create-ddl-jdbc-file-name">create-tables.sql</prop>
            <prop key="eclipselink.drop-ddl-jdbc-file-name">drop-tables.sql</prop>
            <prop key="eclipselink.application-location">target/generated-sources/database</prop>
            <prop key="eclipselink.jdbc.cache-statements">true</prop>
            <prop key="eclipselink.custom.sql.import.file">${oracle.eclipselink.custom.sql.import.file}</prop>
            ...
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManager"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
    <property name="url" value="jdbc:derby:target/memory;create=true"/>
    <property name="username" value="test"/>
    <property name="password" value="test"/>
</bean>

My attempt with H2 is similar but with the proper configurations. In weblogic environemnt everything works as expected.

What I'm missing?

voliveira89
  • 1,134
  • 2
  • 9
  • 22
  • Derby certainly supports multiple transactions. What makes you think the new transaction is not being created? What does your exception say? What does your derby.log say? Have you looked at http://wiki.apache.org/db-derby/LockDebugging – Bryan Pendleton Oct 16 '15 at 14:00
  • Like @OndrejM said, I'm using derby/h2 in embedded in-memory mode. When the application creates a new transaction, derby or h2 restarts the connection and create the database all over again (i.e. imports the custom sql import file again). – voliveira89 Nov 03 '15 at 16:32
  • I know of no such limitation in Derby, nor do other others on the Derby developer list that I've asked about this. I think the behavior you're seeing is due to something in your application or in the way the Spring framework connects to the database. Derby itself does not "restart the connection" nor "import the custom sql import file"; these must be things that Spring is doing, or that your application is doing. If you can break your example down into a standalone plain JDBC program, we could examine what Derby is doing. – Bryan Pendleton Nov 04 '15 at 12:34

1 Answers1

1

It seems you are using derby in embedded in-memory mode. AFAIK, both derby and H2 support concurrent transactions only in standalone mode, when you connect through a TCP connection, but not in embedded mode. Try running derby as a seperate procese and change your database to connect to it.

OndroMih
  • 7,280
  • 1
  • 26
  • 44
  • I believe you're right. Is there any way to boot an standalone instance of derby (or H2) with spring/maven? Or this only possible with a database in embedded in-memory mode? – voliveira89 Nov 03 '15 at 16:35
  • You ay start H2 listening on a TCP port directly from your Java code, like described here: http://stackoverflow.com/a/155237/784594. Then you may execute it from maven using [exec plugin](http://www.vineetmanohar.com/2009/11/3-ways-to-run-java-main-from-maven/). But maybe you just want to run it as standalone server. The point is that you need to access H2 (or Derby) using a TCP connection, with jdbc url like this: `jdbc:h2:tcp://localhost/~/test` and not like this `jdbc:h2:mem:`. Refer [here](http://www.h2database.com/html/cheatSheet.html) to see the difference. Equivalent applies for Derby. – OndroMih Nov 03 '15 at 18:51