事务无法使用JtaTransactionManager完成,而使用JpaTransactionManager工作正常

时间:2016-02-02 12:45:49

标签: spring spring-data spring-data-jpa openjpa jta

使用JTA和Spring Data(1.9.2)时遇到了很大的问题。当我使用JpaTransactionManager时,我的项目工作正常。我也尝试过使用JTA的JdbcTemplate(没有Spring Data),也可以。我已经尝试过OpenJPA(2.2.1)和Hibernate(4.2.8),包括Jetty和Websphere Liberty服务器。他们都使用JTA失败并使用JPA事务管理器正常工作。数据源支持XA,目前是Derby Embedded。 Springframework是v4.2.1

这是我的实体

@Entity
@Table(name = "SAKSSTATUS")
public class SaksStatus implements Serializable {

        @Id
        @Column(name = "ID") 
        private String id;

        public SaksStatus() {};

        public SaksStatus(String id) {
            this.id = id;
        }

}

我的DAO

public interface SaksStatusDao extends JpaRepository<SaksStatus, String> {

}

我的交易

@Transactional
public void test() {
    logger.info("deleting before testing ");
    saksStatusDao.deleteAll();
    logger.info("save...");
    saksStatusDao.save(new SaksStatus("100"));
    logger.info("save OK");
    logger.info("result: {}", saksStatusDao.findAll());
    logger.info("removing ...");
    saksStatusDao.deleteAll();
    logger.info("flush ...");
    saksStatusDao.flush();
}

我的申请背景:

<context:annotation-config/>

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/derbyEmbedded" />

<context:component-scan base-package="no.klp.saksstatus.dao" />

<tx:annotation-driven transaction-manager="transactionManager" />
<tx:jta-transaction-manager />

<jpa:repositories base-package="no.klp.saksstatus.dao"/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="packagesToScan" value="no.klp.saksstatus.dao.entities" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="generateDdl" value="true" />
        </bean>
    </property>
</bean>


<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"></bean>
<bean class="no.klp.saksstatus.services.SaksStatusService"/>

我的持久文件

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
  http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">
    <persistence-unit name="persistenceunit" transaction-type="JTA">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <class>no.klp.saksstatus.dao.entities.SaksStatus</class>
    </persistence-unit>
</persistence>

我在pom.xml中的增强器插件

<plugin>
    <groupId>org.apache.openjpa</groupId>
    <artifactId>openjpa-maven-plugin</artifactId>
    <version>2.3.0</version>
    <configuration>
        <includes>no/klp/saksstatus/dao/entities/**/*.class</includes>
        <addDefaultConstructor>true</addDefaultConstructor>
        <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
        <persistenceXmlFile>${basedir}/META-INF/persistence.xml</persistenceXmlFile>
    </configuration>
    <executions>
        <execution>
            <id>enhancer</id>
            <phase>process-classes</phase>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
        <dependencies>
            <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa</artifactId>
            <version>2.2.1</version>
        </dependency> 
    </dependencies>
</plugin>

因此,在执行我的交易时,我得到了他的日志:

2016-02-02 13:34:52,391 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:367 - Creating new transaction with name [no.klp.saksstatus.services.SaksStatusService.test]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-02-02 13:34:52,423 saksstatus-service INFO  no.klp.saksstatus.services.SaksStatusService:30 - deleting before testing 
2016-02-02 13:34:52,429 saksstatus-service DEBUG org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource:351 - Adding transactional method 'deleteAll' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-02-02 13:34:52,429 saksstatus-service DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory:250 - Returning cached instance of singleton bean 'transactionManager'
2016-02-02 13:34:52,430 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:476 - Participating in existing transaction
2016-02-02 13:34:52,456 saksstatus-service DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils:272 - Opening JPA EntityManager
2016-02-02 13:34:52,457 saksstatus-service DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils:290 - Registering transaction synchronization for JPA EntityManager
[err] 1409  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 26992656> executing prepstmnt 1533150303 SELECT t0.ID FROM SAKSSTATUS t0
[err] 1410  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 26992656> [0 ms] spent
2016-02-02 13:34:52,674 saksstatus-service INFO  no.klp.saksstatus.services.SaksStatusService:32 - save...
2016-02-02 13:34:52,675 saksstatus-service DEBUG org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource:351 - Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-02-02 13:34:52,675 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:476 - Participating in existing transaction
[err] 1525  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 1984659730> executing prepstmnt 715039869 SELECT t0.ID FROM SAKSSTATUS t0 WHERE t0.ID = ? [params=?]
[err] 1526  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 1984659730> [0 ms] spent
2016-02-02 13:34:52,778 saksstatus-service INFO  no.klp.saksstatus.services.SaksStatusService:34 - save OK
2016-02-02 13:34:52,779 saksstatus-service DEBUG org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource:351 - Adding transactional method 'findAll' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
2016-02-02 13:34:52,779 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:476 - Participating in existing transaction
[err] 1539  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 977455988> executing prepstmnt 1441490501 SELECT t0.ID FROM SAKSSTATUS t0
[err] 1539  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 977455988> [0 ms] spent
2016-02-02 13:34:52,781 saksstatus-service INFO  no.klp.saksstatus.services.SaksStatusService:35 - result: []
2016-02-02 13:34:52,781 saksstatus-service INFO  no.klp.saksstatus.services.SaksStatusService:36 - removing ...
2016-02-02 13:34:52,781 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:476 - Participating in existing transaction
[err] 1541  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 1721406628> executing prepstmnt 174725407 SELECT t0.ID FROM SAKSSTATUS t0
[err] 1541  default  TRACE  [Default Executor-thread-2] openjpa.jdbc.SQL - <t 925948525, conn 1721406628> [0 ms] spent
2016-02-02 13:34:52,783 saksstatus-service INFO  no.klp.saksstatus.services.SaksStatusService:38 - flush ...
2016-02-02 13:34:52,783 saksstatus-service DEBUG org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource:351 - Adding transactional method 'flush' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-02-02 13:34:52,784 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:476 - Participating in existing transaction
2016-02-02 13:34:52,785 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:858 - Participating transaction failed - marking existing transaction as rollback-only
2016-02-02 13:34:52,785 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:1072 - Setting JTA transaction rollback-only
2016-02-02 13:34:52,786 saksstatus-service DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory:250 - Returning cached instance of singleton bean 'entityManagerFactory'
2016-02-02 13:34:52,790 saksstatus-service DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils:435 - Closing JPA EntityManager
2016-02-02 13:34:52,802 saksstatus-service DEBUG org.springframework.transaction.jta.JtaTransactionManager:851 - Initiating transaction rollback
[ERROR   ] SRVE0777E: Exception thrown by application class 'org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible:413'
org.springframework.dao.InvalidDataAccessApiUsageException: Can only perform operation while a transaction is active.; nested exception is <openjpa-2.2.1-r422266:1396819 nonfatal user error> org.apache.openjpa.persistence.TransactionRequiredException: Can only perform operation while a transaction is active.
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
    at org.springframework.orm.jpa.DefaultJpaDialect.translateExceptionIfPossible(DefaultJpaDialect.java:122)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy41.flush(Unknown Source)
    at no.klp.saksstatus.services.SaksStatusService.test(SaksStatusService.java:39)
    at no.klp.saksstatus.services.SaksStatusService$$FastClassBySpringCGLIB$$fcbe12b7.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at no.klp.saksstatus.services.SaksStatusService$$EnhancerBySpringCGLIB$$db202906.test(<generated>)
    at no.klp.saksstatus.TestServlet.doGet(TestServlet.java:49)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1287)
    at [internal classes]
Caused by: <openjpa-2.2.1-r422266:1396819 nonfatal user error> org.apache.openjpa.persistence.TransactionRequiredException: Can only perform operation while a transaction is active.
    at org.apache.openjpa.kernel.BrokerImpl.assertActiveTransaction(BrokerImpl.java:4694)
    at org.apache.openjpa.kernel.DelegatingBroker.assertActiveTransaction(DelegatingBroker.java:1386)
    at org.apache.openjpa.persistence.EntityManagerImpl.flush(EntityManagerImpl.java:662)
    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:497)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344)
    at com.sun.proxy.$Proxy38.flush(Unknown Source)
    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:497)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:293)
    at com.sun.proxy.$Proxy38.flush(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.flush(SimpleJpaRepository.java:486)
    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:497)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:483)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:468)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ... 23 more

与使用JPA事务管理器的一个区别是,只记录了唯一的SELECT语句。 INSERT语句未执行(使用JPA事务管理器时,它们全部记录)。

保存条目(saksStatusDao.save(new SaksStatus(“100”));)应该创建一个INSERT。最后应该执行DELETE。

一切似乎都很好,但最后一次刷新()开始回滚,请给我一些建议来解决这个问题。现在已经被打了一个月......

使用JPA事务管理器不是一个选项,因为我想使用JTA和allowCustomIsolationLevels来使用UNCOMITTED_READ。

/Bjørn-Willy Arntzen,挪威奥斯陆

0 个答案:

没有答案