Spring 贾西格·卡斯。如何使用JpaTicketRegistry启用事务?

Spring 贾西格·卡斯。如何使用JpaTicketRegistry启用事务?,spring,transactions,aop,cas,jasig,Spring,Transactions,Aop,Cas,Jasig,使用maven覆盖。我只配置了cas.properties(数据库连接部分),ticketRegistry.xml和pom.xml,如前所述。还稍微修改了类JpaTicketRegistry,以获取更多调试信息。从log可以看出,getTicket方法没有事务(postgres@Lob(oid)需要)。软件版本:tomcat8.0.28,psql(PostgreSQL)9.4.4,(Jasig)CAS4.1.0 // @Transactional(readOnly=true) Spring AO

使用maven覆盖。我只配置了cas.properties(数据库连接部分),ticketRegistry.xmlpom.xml,如前所述。还稍微修改了类JpaTicketRegistry,以获取更多调试信息。从log可以看出,getTicket方法没有事务(postgres@Lob(oid)需要)。软件版本:tomcat8.0.28,psql(PostgreSQL)9.4.4,(Jasig)CAS4.1.0

// @Transactional(readOnly=true) Spring AOP Declarative transaction is being used, so @Transactional(readOnly=true) it's just some old code.
@Override
public Ticket getTicket(final String ticketId) {
    return getProxiedTicketInstance(getRawTicket(ticketId));
}

/**
 * Gets the ticket from the database, as is.
 *
 * @param ticketId the ticket id
 * @return the raw ticket
 */
private Ticket getRawTicket(final String ticketId) {
    try {

        if(TransactionSynchronizationManager.isActualTransactionActive()) {
            logger.debug("Ticket getRawTicket - Active transaction found");
        } else {
            logger.error("Ticket getRawTicket No active transaction found");
        }

        if (ticketId.startsWith(this.ticketGrantingTicketPrefix)) {
            return entityManager.find(TicketGrantingTicketImpl.class, ticketId);
        }

        return entityManager.find(ServiceTicketImpl.class, ticketId);
    } catch (final Exception e) {
        logger.error("Error2 getting ticket from registry.", e);
        logger.error("Error getting ticket {} from registry.", ticketId, e);
    }
    return null;
}
pom.xml

      <dependency>
    <groupId>org.jasig.cas</groupId>
    <artifactId>cas-server-support-jdbc</artifactId>
    <version>${cas.version}</version>
  </dependency>

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>${hibernate.core.version}</version>
    <scope>runtime</scope>
  </dependency>

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>${hibernate.core.version}</version>
    <scope>runtime</scope>
  </dependency>

  <dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>${c3p0.version}</version>
  </dependency>

  <dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.4-1203-jdbc41</version>
  </dependency>

  <dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.1-api</artifactId>
    <version>1.0.0.Final</version>
  </dependency>
</dependencies>
...
<properties>
<cas.version>4.1.0</cas.version>
<pac4j.version>1.7.1</pac4j.version>
<hibernate.core.version>4.3.10.Final</hibernate.core.version>
<c3p0.version>0.9.5.1</c3p0.version>
</properties>
UPD1-也尝试了相同的配置,但在mysql上-没有运气-javax.persistence.TransactionRequiredException:没有可用的事务实体管理器

2015-10-20 00:13:31,408 DEBUG [org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver] - <Resolving exception from handler [[FlowHandlerMapping.DefaultFlowHandler@7f77437d]]: org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.jasig.cas.web.flow.GenerateServiceTicketAction@7dd5c8c0 in state 'generateServiceTicket' of flow 'login' -- action execution attributes were 'map[[empty]]'>
2015-10-20 00:13:31,409 DEBUG [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] - <Resolving exception from handler [[FlowHandlerMapping.DefaultFlowHandler@7f77437d]]: org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.jasig.cas.web.flow.GenerateServiceTicketAction@7dd5c8c0 in state 'generateServiceTicket' of flow 'login' -- action execution attributes were 'map[[empty]]'>
2015-10-20 00:13:31,410 DEBUG [org.jasig.cas.web.FlowExecutionExceptionResolver] - <Ignoring the received exception due to a type mismatch
org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.jasig.cas.web.flow.GenerateServiceTicketAction@7dd5c8c0 in state 'generateServiceTicket' of flow 'login' -- action execution attributes were 'map[[empty]]'
....
Caused by: javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275)
at com.sun.proxy.$Proxy52.merge(Unknown Source)
at org.jasig.cas.ticket.registry.JpaTicketRegistry.updateTicket(JpaTicketRegistry.java:61)
at org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry$TicketDelegator.updateTicket(AbstractDistributedTicketRegistry.java:101)
at org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry$TicketGrantingTicketDelegator.grantServiceTicket_aroundBody6(AbstractDistributedTicketRegistry.java:234)
at org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry$TicketGrantingTicketDelegator$AjcClosure7.run_aroundBody0(AbstractDistributedTicketRegistry.java:1)
at org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry$TicketGrantingTicketDelegator$AjcClosure7$AjcClosure1.run_aroundBody0(AbstractDistributedTicketRegistry.java:1)
at org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry$TicketGrantingTicketDelegator$AjcClosure7$AjcClosure1$AjcClosure1.run(AbstractDistributedTicketRegistry.java:1)
at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149)
at org.jasig.inspektr.aspect.TraceLogAspect.traceMethod(TraceLogAspect.java:44)
2015-10-20 00:13:31408调试[org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver]-
2015-10-20 00:13:31409调试[org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver]-

2015-10-20 00:13:31410调试[org.jasig.cas.web.FlowExecutionExceptionResolver]-日志中清楚地提到了错误,即无法使用自动提交保存大型对象。我正在以这种方式在我的配置中禁用它们:

  <beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close">
        <beans:property name="driverClassName" value="org.postgresql.Driver"/>
        <beans:property name="url"
                        value="jdbc:postgresql://domain:port/db"/>
        <beans:property name="username" value="user"/>
        <beans:property name="password" value="password"/>
        <beans:property name="removeAbandoned" value="true"/>
        <beans:property name="removeAbandonedTimeout" value="20"/>
        <beans:property name="defaultAutoCommit" value="false"/>
    </beans:bean>

检查我的最后一个属性并禁用它。享受。

看起来有过时/误导性的说明:

Adjust the src/main/webapp/WEB-INF/spring-configuration/ticketRegistry.xml with the following
解决方案是:dataSourceentityManagerFactoryconfigs必须位于定义了
的相同上下文/文件中(在我的例子中是src/main/webapp/WEB-INF/cas servlet.xml


多亏了

在4.1.x@commit中删除了事务装饰程序,取而代之的是aop切入点

调试此问题时最困难的部分是Postgres的错误消息很容易被误解(将其发送到兔子洞中)。它会看到您没有活动事务,并且状态为您正在自动提交模式下运行,这会导致调试

添加一些额外的aop切入点和tx:advice条目和事务应按预期开始应用

<tx:advice id="txAdviceTicketReg" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="add*" read-only="false"/>
        <tx:method name="delete*" read-only="false"/>
        <tx:method name="save*" read-only="false"/>
        <tx:method name="update*" read-only="false"/>
        <tx:method name="get*" read-only="true"/>
        <tx:method name="*" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="ticketRegistryOperations" expression="execution(* org.jasig.cas.ticket.registry.JpaTicketRegistry.*(..))"/>
    <aop:pointcut id="abstractTicketRegistryOperations" expression="execution(* org.jasig.cas.ticket.registry.AbstractTicketRegistry.*(..))"/>
    <aop:pointcut id="ticketRegistryLockingOperations" expression="execution(* org.jasig.cas.ticket.registry.support.JpaLockingStrategy.*(..))"/>

    <aop:advisor advice-ref="txAdviceTicketReg" pointcut-ref="ticketRegistryOperations"/>
    <aop:advisor advice-ref="txAdviceTicketReg" pointcut-ref="abstractTicketRegistryOperations"/>
    <aop:advisor advice-ref="txAdviceTicketReg" pointcut-ref="ticketRegistryLockingOperations"/>
</aop:config>

如果您需要查找其他类以添加异常。添加以下记录器条目以观察AOP正在做什么

<Logger name="org.jasig.inspektr" level="trace" additivity="false">
    <AppenderRef ref="Console" />
</Logger>


感谢您的回复,但这没有帮助。Got javax.persistence.TransactionRequiredException:没有与mysql配置相同的事务EntityManager可用,因此这不是postgres特有的问题。这样做是可行的,但您的Hibernate配置是错误的。我猜您的服务层没有使用事务性注释进行注释,而您的dao没有使用存储库进行注释。
<tx:advice id="txAdviceTicketReg" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="add*" read-only="false"/>
        <tx:method name="delete*" read-only="false"/>
        <tx:method name="save*" read-only="false"/>
        <tx:method name="update*" read-only="false"/>
        <tx:method name="get*" read-only="true"/>
        <tx:method name="*" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="ticketRegistryOperations" expression="execution(* org.jasig.cas.ticket.registry.JpaTicketRegistry.*(..))"/>
    <aop:pointcut id="abstractTicketRegistryOperations" expression="execution(* org.jasig.cas.ticket.registry.AbstractTicketRegistry.*(..))"/>
    <aop:pointcut id="ticketRegistryLockingOperations" expression="execution(* org.jasig.cas.ticket.registry.support.JpaLockingStrategy.*(..))"/>

    <aop:advisor advice-ref="txAdviceTicketReg" pointcut-ref="ticketRegistryOperations"/>
    <aop:advisor advice-ref="txAdviceTicketReg" pointcut-ref="abstractTicketRegistryOperations"/>
    <aop:advisor advice-ref="txAdviceTicketReg" pointcut-ref="ticketRegistryLockingOperations"/>
</aop:config>
<Logger name="org.jasig.inspektr" level="trace" additivity="false">
    <AppenderRef ref="Console" />
</Logger>