Spring 贾西格·卡斯。如何使用JpaTicketRegistry启用事务?
使用maven覆盖。我只配置了cas.properties(数据库连接部分),ticketRegistry.xml和pom.xml,如前所述。还稍微修改了类JpaTicketRegistry,以获取更多调试信息。从log可以看出,getTicket方法没有事务(postgres@Lob(oid)需要)。软件版本:tomcat8.0.28,psql(PostgreSQL)9.4.4,(Jasig)CAS4.1.0Spring 贾西格·卡斯。如何使用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
// @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
解决方案是:dataSource和entityManagerFactoryconfigs必须位于定义了
的相同上下文/文件中(在我的例子中是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>