2011-09-26 117 views
13

我正在使用Spring 3與Hibernate 3.我試圖配置Spring聲明式事務,但無論我嘗試什麼,Spring事務都沒有開始。Spring @Transaction未開始交易

這裏是我的配置

文件:的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> 

我有一個類ServiceLocatorImpl它實現的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"); 
     } 
     ...... 
} 
    .... 
} 

在我看來,我的所有配置是正確的。但是,當調用executeService方法時,TransactionSynchronizationManager.isActualTransactionActive()始終返回false。

請幫我解決這個問題。讓我知道是否需要更多信息。

更新: 我了有線的服務定位成其他類之一,如下:

@Autowired 
private ServiceLocator serviceLocator; // ServiceLocator is interface 

我使用Spring 3.0.0版本。

executeService()是ServiceLocator接口中定義的方法之一。我更新了代碼來拋出異常,而不是隻記錄一個錯誤。以下是堆棧跟蹤,我在此跟蹤中看不到任何代理創建。請幫忙。

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) 

更新[解決] 我得到了這個問題解決。在給出答案之前,我需要提供更多信息。我在我的項目中使用Spring MVC。控制DispatchServlet在web.xml中配置。此前端控制器具有配置xml文件abc-servlet.xml(abc是web.xml中的servlet名稱)。我還有其他的彈簧配置文件,這些文件在web.xml中定義爲context-param。其中一個文件是applicationContext-hibernate.xml文件。

我在applicationContext-hibernate.xml文件中定義了txManager<tx:annotation-driven />。今天,我想知道是否@Autowired和@Transactional工作一起,所以我谷歌的信息,發現這個線程

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

線程談論類似的問題,而這個問題解決了。

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

想,我也動了我的<tx:annotation-driven />到ABC-servlet.xml文件和它的工作。現在

我的日誌shoulding所需的信息:

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

感謝大家的幫助。可能這些信息會對某人有所幫助。我仍然希望聽到有關解釋,爲什麼它不能提前工作。

+0

'executeService()'是否實現了'ServiceLocator'中定義的方法?你能拋出一個這種方法的異常,而不是記錄一個錯誤並粘貼堆棧跟蹤?我想查看交易方面是否在堆棧中。同時請提供確切的Spring版本。 –

+0

你能說明如何調用該方法嗎?你也可以檢查什麼是ServiceLocator的實例類型,它是一個代理實例嗎? –

+0

我已經更新了所需堆棧軌跡的問題。更新後,我在調用bean中注入了'ServiceLocator'實例。 'serviceService()'在'ServiceLocator'接口中定義。 –

回答

4

我的猜測是,你正在試圖做一些事情,如:

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

,然後是驚訝,有沒有交易。事務管理和所有其他Spring服務僅適用於應用程序上下文*中的bean。您需要以某種方式從上下文中獲取實例,而不是僅實例化一個實例。否則,您的定位器bean位於與聲明tx:annotation-driven的應用程序環境不同的應用程序環境中。

*除非你使用AspectJ build- or load-time bytecode weaving春暖花開。

編輯:問題正是我所說的(第二部分)。您創建兩個應用程序上下文。你在第一個創建你的ServiceLocator,但是你只在第二個中啓用註解驅動的事務。您似乎不瞭解上下文之間的界限。通常 - 至少在我的經驗中 - 「業務」bean,就像ServiceLocator一樣,存在於根環境中,該環境由ContextLoaderListener開始,並通過contextConfigLocation進行配置。配置DispatcherServlet或由DispatcherServlet使用的控制器和其他bean位於與由該*-servlet.xml文件配置的servlet相關的另一個上下文中。這個上下文變成了根上下文的子上下文,並且其中的bean可以從根上下文注入bean,儘管反過來也是如此。

從我的角度來看,通過將tx:annotation-driven添加到與DispatcherServlet關聯的子上下文中,您已經破壞了比以前更糟糕的事情。相反,您應該確保ServiceLocator是在根環境中創建的,其中事務服務已經可用並且屬於它們所在的位置。

+0

我沒有實例化ServiceLocator,而是我正在注入服務定位器bean。來電信息在原始文章中更新。 –

+0

@ user746528:更新了我的答案 –

1

您應該簡單地重命名 「txManager」 到 「transactionManager的」。來自EnableTransactionManagementJavaDoc

...在XML的情況下,名稱是「transactionManager」。 <tx:annotation-driven/>被硬連接以默認尋找名爲「transactionManager」的bean ...