2011-09-26 1168 views
13

Estoy usando Spring 3 con Hibernate 3. Estoy intentando configurar la transacción declarativa de Spring, pero no importa lo que intente, la transacción de Spring no se está iniciando.Spring @Transaction no inicia transacciones

Aquí está mi configuración

del archivo: applicationContext-hibernate.xml

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

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
<property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<bean id="mdbDataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
... 
</bean> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
<property name="dataSource" ref="mdbDataSource" /> 
    <property name="annotatedClasses"> 
..... 
</bean> 

Tengo un ServiceLocatorImpl clase que implementa la interfaz ServiceLocator

@Service("serviceLocator") 
@Transactional 
public class ServiceLocatorImpl implements ApplicationContextAware, Serializable, ServletContextAware, ServiceLocator { 
public ResultObject executeService(Map objArgs) 
{ 
     if(TransactionSynchronizationManager.isActualTransactionActive()) { 
      LOGGER.debug("ServiceLocator:executeService - Active transaction found"); 
     } else { 
     LOGGER.error("No active transaction found"); 
     } 
     ...... 
} 
    .... 
} 

Me parece que toda la configuración de mi es correcto. Pero cuando se llama al método executeService, TransactionSynchronizationManager.isActualTransactionActive() siempre devuelve falso.

Ayúdeme a resolver este problema. Avíseme si se requiere más información.

Actualización: He cableado el ServiceLocator en una de las otras clases, de la siguiente manera:

@Autowired 
private ServiceLocator serviceLocator; // ServiceLocator is interface 

estoy usando la versión 3.0.0 de primavera.

executeService() es uno de los métodos definidos en la interfaz ServiceLocator. Actualicé el código para lanzar una excepción en lugar de solo registrar un error. A continuación se muestra el seguimiento de pila, no veo ninguna creación de proxy en este seguimiento. Por favor ayuda.

java.lang.RuntimeException: No active transaction found 
at com.nihilent.venice.common.service.ServiceLocatorImpl.logTransactionStatus(ServiceLocatorImpl.java:102) 
at com.nihilent.venice.common.service.ServiceLocatorImpl.executeService(ServiceLocatorImpl.java:47) 
at com.nihilent.venice.web.controller.CommonController.handleRequest(CommonController.java:184) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
at java.lang.reflect.Method.invoke(Method.java:597) 
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710) 
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167) 
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414) 
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) 
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) 
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) 
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:381) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) 
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436) 
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374) 
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302) 
at org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:709) 
at org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:680) 
at org.apache.jsp.index_jsp._jspService(index_jsp.java:57) 
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:386) 
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313) 
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) 
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) 
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) 
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:381) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at com.nihilent.venice.web.filter.DyanamicResponseHeaderFilter.doFilter(DyanamicResponseHeaderFilter.java:33) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:118) 
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:52) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149) 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at com.nihilent.venice.web.filter.RequestFilter.doFilter(RequestFilter.java:44) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
at java.lang.Thread.run(Thread.java:619) 

Update [Resuelto] logré introducir el tema. Antes de dar la respuesta de cómo se solucionó, necesito proporcionar más información. Estoy usando Spring MVC en mi proyecto. El control DispatchServlet está configurado en web.xml. Este controlador frontal tiene un archivo xml de configuración abc-servlet.xml (abc es el nombre del servlet en web.xml). También tengo otros archivos de configuración de primavera que se definen como context-param en web.xml. Uno de los archivos es applicationContext-hibernate.xml.

Definí txManager y <tx:annotation-driven />, en el archivo applicationContext-hibernate.xml. Hoy me preguntaba si @Autowired y el trabajo con @Transactional juntos, así que Google la información, y encontrado este hilo

http://forum.springsource.org/showthread.php?48815-Repository-Autowired-Transaction-not-returning-proxy-and-causes-exception

La charla hilo sobre problema similar, y esto resuelve el problema.

I implemented one of the suggestion and added <tx:annotation-driven .../> to my servlet's application context xml and it fixes the problem.

pensando que también se ha llevado mi <tx:annotation-driven /> en el archivo abc-servlet.xml y funcionó.

Mis registros son ahora shoulding los mensajes requeridos:

[venice] DEBUG [http-8080-1] 27 Sep 2011 14:24:06,312 ServiceLocatorImpl.logTransactionStatus(100) | ServiceLocator:executeService - Active transaction found

Gracias a todos por ayudar. Puede ser que esta información sea útil para alguien. Todavía me gustaría escuchar acerca de la explicación de por qué no estaba funcionando antes.

+0

¿'executeService()' implementa un método definido en 'ServiceLocator'? ¿Puedes lanzar una excepción desde este método en lugar de registrar un error y pegar el seguimiento de la pila? Quiero ver si el aspecto de la transacción está en la pila. También proporcione la versión exacta de Spring. –

+0

¿Puedes mostrar cómo se llama el método? También puede verificar cuál es el tipo de instancia de ServiceLocator, ¿es una instancia de proxy? –

+0

He actualizado la pregunta con la pista de pila requerida. Como estoy actualizado, estoy inyectando la instancia 'ServiceLocator' en el bean que llama. 'executeService()' se define en la interfaz 'ServiceLocator'. –

Respuesta

4

Mi conjetura sería que usted está tratando de hacer algo como:

ServiceLocator locator = new ServiceLocatorImpl(); 
... 
locator.executeService(someMap); 

y luego ser sorprendido de que no hay ninguna transacción. La gestión de transacciones y todos los demás servicios de Spring solo se aplican a los beans en el contexto de la aplicación *. Necesita obtener su instancia del contexto de una forma u otra en lugar de simplemente crear una instancia. De lo contrario, su bean localizador se encuentra en un contexto de aplicación diferente al que declara tx:annotation-driven.

* A menos que esté usando AspectJ build- or load-time bytecode weaving con Spring.

Edit: El problema fue exactamente lo que dije (la segunda parte). Usted crea dos contextos de aplicación. Usted estaba creando su ServiceLocator en el primero, pero solo habilitó las transacciones basadas en anotaciones en el segundo. Parece que no comprende los límites entre los contextos. Generalmente, al menos en mi experiencia, los beans "empresariales", como su ServiceLocator, viven en el contexto raíz, que es el iniciado por el ContextLoaderListener y configurado a través del contextConfigLocation. Los controladores y otros beans que configuran o usan un DispatcherServlet viven en otro contexto asociado con ese servlet configurado mediante el archivo *-servlet.xml. Este contexto se convierte en un contexto secundario del contexto raíz, y los beans en él pueden ser inyectados con beans desde el contexto raíz, aunque no viceversa.

Desde mi punto de vista, ha roto las cosas peor que antes agregando tx:annotation-driven al contexto secundario asociado a su DispatcherServlet. En su lugar, debe asegurarse de que ServiceLocator se cree en el contexto raíz, donde los servicios transaccionales ya están disponibles y están donde pertenecen.

+0

No estoy instanciando el ServiceLocator, en su lugar, estoy inyectando el bean de localización de servicios. La información de llamada se actualiza en la publicación original. –

+0

@ user746528: Actualicé mi respuesta –

1

Simplemente debe cambiar el nombre de su "txManager" a "transactionManager". Desde el EnableTransactionManagement 's JavaDoc:

... en el caso de XML, el nombre es "transactionManager". El <tx:annotation-driven/> está cableado para buscar un bean llamado "transactionManager" de forma predeterminada ...

Cuestiones relacionadas