2011-09-26 17 views
13

Sto utilizzando Spring 3 con Hibernate 3. Sto tentando di configurare la transazione dichiarativa di Spring, ma non importa quello che provo, la transazione Spring non è iniziata.Spring @Transaction non avvia le transazioni

Ecco la mia configurazione

File: 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> 

Ho un ServiceLocatorImpl classe che implementa l'interfaccia 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"); 
     } 
     ...... 
} 
    .... 
} 

Mi sembra che tutta la mia configurazione è corretta. Ma quando viene chiamato il metodo executeService, TransactionSynchronizationManager.isActualTransactionActive() restituisce sempre false.

Per favore aiutatemi a risolvere questo problema. Fammi sapere se sono necessarie ulteriori informazioni.

Aggiornamento: Ho cablato il ServiceLocator in una delle altre classi, come segue:

@Autowired 
private ServiceLocator serviceLocator; // ServiceLocator is interface 

Sto usando Primavera 3.0.0 versione.

executeService() è il metodo definito nell'interfaccia di ServiceLocator. Ho aggiornato il codice per generare un'eccezione anziché registrare semplicemente un errore. Di seguito è riportata la traccia dello stack, non vedo alcuna creazione di proxy in questa traccia. Per favore aiuto.

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) 

Aggiornamento [Risolto] ho avuto il problema risolto. Prima di dare la risposta come è stato risolto, ho bisogno di fornire ulteriori informazioni. Sto usando Spring MVC nel mio progetto. Il controllo DispatchServlet è configurato nel web.xml. Questo front controller ha un file xml di configurazione abc-servlet.xml (abc è il nome del servlet in web.xml). Ho anche altri file di configurazione di primavera che sono definiti come context-param in web.xml. Uno dei file è il file applicationContext-hibernate.xml.

Ho definito il <tx:annotation-driven />, nel file applicationContext-hibernate.xml. Oggi mi chiedevo se @Autowired e lavorare con @Transactional insieme, così ho google le informazioni, e ho trovato questa discussione

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

Il discorso thread su problema simile, e questo risolve il problema.

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

Pensare che ho anche spostato la mia <tx:annotation-driven /> in file di abc-servlet.xml e ha funzionato.

miei registri sono ora shoulding i messaggi richiesti:

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

Grazie a tutti per l'aiuto. Potrebbe essere questa informazione sarà utile a qualcuno. Mi piacerebbe ancora sentire la spiegazione del perché non funzionava prima.

+0

È 'executeService()' che implementa un metodo definito in 'ServiceLocator'? Puoi lanciare un'eccezione da questo metodo invece di registrare un errore e incollare la traccia dello stack? Voglio vedere se l'aspetto della transazione è in pila. Si prega di fornire anche la versione esatta di Spring. –

+0

Puoi mostrare come viene chiamato il metodo? Puoi anche controllare qual è il tipo di istanza di ServiceLocator, è un'istanza proxy? –

+0

Ho aggiornato la domanda con la traccia dello stack richiesta. Come aggiornato sto iniettando l'istanza 'ServiceLocator' nel bean chiamante. 'executeService()' è definito nell'interfaccia 'ServiceLocator'. –

risposta

4

La mia ipotesi è che si sta cercando di fare qualcosa di simile:

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

e poi di essere sorpreso che non c'è nessuna transazione. La gestione delle transazioni e tutti gli altri servizi Spring si applicano solo ai bean nel contesto dell'applicazione *. È necessario ottenere l'istanza dal contesto in un modo o nell'altro anziché semplicemente istanziarne uno. Oppure il tuo bean locator si trova in un contesto applicativo separato rispetto a quello in cui dichiari tx:annotation-driven.

* A meno che non si stia utilizzando AspectJ build- or load-time bytecode weaving con Spring.

Modifica: Il problema era esattamente quello che ho detto (la seconda parte). Si creano due contesti di applicazione. Stavi creando il tuo ServiceLocator nel primo, ma hai abilitato solo le transazioni guidate dalle annotazioni nel secondo. Sembra non capire i confini tra i contesti. In generale - almeno nella mia esperienza - i bean "business", come il ServiceLocator, vivono nel contesto di root, che è quello avviato da ContextLoaderListener e configurato tramite contextConfigLocation. I controller e altri bean che configurano o sono utilizzati da DispatcherServlet risiedono in un altro contesto associato a quel servlet configurato dal file *-servlet.xml. Questo contesto diventa un contesto secondario del contesto di root e i bean in esso contenuti possono essere iniettati con bean dal contesto di root, sebbene non viceversa.

Dal mio punto di vista, hai rotto le cose peggio di prima aggiungendo tx:annotation-driven al contesto figlio associato al DispatcherServlet. Invece, è necessario assicurarsi che ServiceLocator sia stato creato nel contesto root, dove i servizi transazionali sono già disponibili e sono al loro posto.

+0

Non sto istanziando il ServiceLocator, invece sto iniettando il bean del localizzatore di servizi. Le informazioni sulla chiamata vengono aggiornate nel post originale. –

+0

@ user746528: aggiornata la mia risposta –

1

Dovresti semplicemente rinominare il tuo "txManager" in "transactionManager". Da 's JavaDoc il EnableTransactionManagement:

... nel caso di XML, il nome è "transactionManager". Il <tx:annotation-driven/> è cablato per cercare un bean denominato "transactionManager" per impostazione predefinita ...

Problemi correlati