2011-09-26 292 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 ...