【问题标题】:Spring and H2 or Derby - Multiple TransactionsSpring 和 H2 或 Derby - 多个事务
【发布时间】:2016-01-15 01:54:15
【问题描述】:

我有一个使用 Spring 的项目。在本地环境中,我使用 Derby(与 Jetty),它为我提供了在此环境中所需的性能(在生产中使用 Oracle 和 Weblogic)。

问题是我在某些特定操作中需要新事务。这个特定的操作使用注解@Transactional(propagation=REQUIRES_NEW)。

问题在于,对于 Derby,当应创建新事务时,操作会挂起并到期。我尝试使用 H2,但在创建新事务的同一时刻,数据库重新启动,这意味着表被删除并重新创建。

Derby 和 H2 不支持多笔交易?我找不到任何与我相反的东西。

我的数据库配置是:

<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>

我对 H2 的尝试类似,但配置正确。在 weblogic 环境中,一切都按预期工作。

我错过了什么?

【问题讨论】:

  • Derby 当然支持多个事务。是什么让您认为没有创建新交易?你的例外说明了什么?你的 derby.log 说什么?你看过wiki.apache.org/db-derby/LockDebugging
  • 就像@OndrejM 所说,我在嵌入式内存模式下使用 derby/h2。当应用程序创建新事务时,derby 或 h2 重新启动连接并重新创建数据库(即再次导入自定义 sql 导入文件)。
  • 我知道 Derby 中没有这样的限制,我询问过的 Derby 开发人员列表中的其他其他人也不知道。我认为您看到的行为是由于您的应用程序中的某些内容或 Spring 框架连接到数据库的方式造成的。 Derby 本身不会“重启连接”,也不会“导入自定义 sql 导入文件”;这些必须是 Spring 正在做的事情,或者您的应用程序正在做的事情。如果您可以将您的示例分解为一个独立的纯 JDBC 程序,我们可以检查 Derby 正在做什么。

标签: spring jpa transactions derby h2


【解决方案1】:

您似乎在嵌入式内存模式下使用 derby。 AFAIK,当您通过 TCP 连接连接时,derby 和 H2 仅在独立模式下支持并发事务,但在嵌入式模式下不支持。尝试将 derby 作为单独的进程运行并更改数据库以连接到它。

【讨论】:

  • 我相信你是对的。有没有办法用spring/maven启动一个独立的derby(或H2)实例?或者这只有在嵌入式内存模式的数据库中才有可能?
  • 您可以直接从您的 Java 代码启动 H2 侦听 TCP 端口,如下所述:stackoverflow.com/a/155237/784594。然后你可以使用exec plugin从maven执行它。但也许您只想将它​​作为独立服务器运行。关键是您需要使用 TCP 连接访问 H2(或 Derby),jdbc url 像这样:jdbc:h2:tcp://localhost/~/test 而不是像这样的jdbc:h2:mem:。请参阅here 以查看差异。等效适用于德比。
猜你喜欢
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 2016-03-28
  • 2016-09-25
  • 2017-04-06
相关资源
最近更新 更多