我们正在尝试配置 Spring 应用程序以使用 JTA 事务。这并不是说它失败了,而是我们尝试的一切都只是执行选择并忽略了我们的持久性操作。
正如您在以下日志中看到的,即使运行了 save 语句,也没有插入语句,既没有异常,也没有错误/警告日志
服务器日志
DEBUG [xxxx.xxxx.persistence] (http--0.0.0.0-8080-1) execute $Proxy363.save(whatever.core.entities.XxxAssignedTime@51a8c542)
DEBUG [org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource] (http--0.0.0.0-8080-1) Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (http--0.0.0.0-8080-1) Returning cached instance of singleton bean 'transactionManager'
DEBUG [org.springframework.transaction.jta.JtaTransactionManager] (http--0.0.0.0-8080-1) Participating in existing transaction
INFO [xxxx.xxxx.impl.BpmnUserBusinessImpl] (http--0.0.0.0-8080-1) Last Assigned Time Updated to *******, Thu Sep 06 15:48:48 ICT 2012
这就像应用程序服务器认为一切正常一样。然而,如果您检查表,则没有进行任何插入或更新。
我们打算与 Spring 应用程序一起使用的数据源已成功地由运行在同一应用程序服务器中的 Java EE war 应用程序与 JTA 事务一起使用。
由于我们不知道问题可能出在哪里,所以我想将其全部放在完整的上下文中。
- Spring 3.1.2-RELEASE
- 休眠4.1.5.Final
- spring-data-jpa 1.1.1.Final
- Apache 轴1.4
- jboss AS7.1
- 数据库:Oracle 10g
为了让它发挥作用,我们一直在尝试各种疯狂的配置,所以我将在这里复制最简单的一个。
standalone.xml
<datasource jta="true" jndi-name="java:jboss/datasources/EngineDS" pool-name="EngineDS" enabled="true" use-java-context="true" use-ccm="true">
<connection-url>jdbc:oracle:thin:@server:port:****</connection-url>
<driver>oracle</driver>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>100</max-pool-size>
<prefill>true</prefill>
</pool>
<security>
<user-name>****</user-name>
<password>****</password>
</security>
<statement>
<prepared-statement-cache-size>32</prepared-statement-cache-size>
<share-prepared-statements>true</share-prepared-statements>
</statement>
</datasource>
<drivers>
<driver name="oracle" module="com.oracle.ojdbc6">
<xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
</driver>
</drivers>
web.xml
[...]
<resource-ref id="DS">
<res-ref-name>EngineDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
<mapped-name>java:jboss/datasources/EngineDS</mapped-name>
</resource-ref>
[...]
spring-jpa-config.xml
<jpa:repositories base-package="whatever.core.repositories" />
<jee:jndi-lookup id="dataSource" jndi-name="EngineDS" cache="true" resource-ref="true" expected-type="javax.sql.DataSource"/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="whatever.core.entities" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${hibernate.show_sql}" />
<property name="generateDdl" value="${jpa.generateDdl}" />
<property name="databasePlatform" value="${jpa.dialect}" />
</bean>
</property>
</bean>
<tx:annotation-driven />
<tx:jta-transaction-manager />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>
我们过去曾制作过 jboss AS5/Spring 3.0 应用程序来处理 JTA 事务,所以这不是我第一次这样做,并且我们一直在寻找我能找到的所有可能的博客和开源项目。然而,任何对每个人来说似乎都很顺利的事情在我的应用程序中似乎都被忽略了。我确信我们在某个地方遗漏了一些非常愚蠢的东西,但到目前为止我们已经尝试了 70 多种不同的配置,但似乎没有一个能够在不尝试 JTA 时进行简单的插入。
(我们使用 axis 1.4 的事实可能相关或不相关,但我想告诉大家,因为我们的应用程序仅在 Web 服务调用后触发操作)。此时我们开始相信配置超自然事件......
有人有任何线索吗?
最佳答案
事实证明,由于我使用的是 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
,上述配置不起作用。
要拥有 JTA,我应该查找 JBoss 容器管理的实体管理器 spring-jpa.config.xml
:
<!-- lookup the container-managed JPA-EMF -->
<!-- the JNDI name is specified in META-INF/persistence.xml -->
<!-- SEE: https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide#JPAReferenceGuide-BindingEntityManagerFactorytoJNDI -->
<jee:jndi-lookup id="defaultPu" jndi-name="java:jboss/defaultPu" />
并在 META-INF/persistence.xml
中将实体管理器工厂绑定(bind)到 JNDI:
<!-- bind the EMF in JNDI -->
<property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/defaultPu" />
所以,我让 Jboss 引导 JPA,这样 JTA 事务就可以工作了!
关于jpa - 无法使 JTA 在带有 spring 3.1 的 jboss AS7.1 上工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12296062/