Spring @Transaction not starting transactions
Solution 1
My guess would be that you're trying to do something like:
ServiceLocator locator = new ServiceLocatorImpl();
...
locator.executeService(someMap);
and then being surprised that there's no transaction. Transaction management and all other Spring services only apply to beans in the application context*. You need to get your instance from the context one way or another instead of just instantiating one. Or else your locator bean is in a separate application context than the one where you declare tx:annotation-driven
.
*Unless you're using AspectJ build- or load-time bytecode weaving with Spring.
Edit: The problem was exactly what I said (the second part). You create two application contexts. You were creating your ServiceLocator in the first one, but you only enabled annotation-driven transactions in the second one. You appear to not understand the boundaries between the contexts. Generally--at least in my experience--the "business" beans, like your ServiceLocator, live in the root context, which is the one started by the ContextLoaderListener
and configured via contextConfigLocation
. Controllers and other beans that configure or are used by a DispatcherServlet live in another context associated with that servlet which is configured by the *-servlet.xml
file. This context becomes a child context of the root context, and the beans in it can be injected with beans from the root context, though not vice versa.
From my perspective, you've broken things worse than they were before by adding tx:annotation-driven
to the child context associated to your DispatcherServlet. Instead, you should ensure that the ServiceLocator is created in the root context, where transactional services are already available and are where they belong.
Solution 2
You should simply rename your "txManager" to "transactionManager". From the EnableTransactionManagement
's JavaDoc:
…in the XML case, the name is "transactionManager". The
<tx:annotation-driven/>
is hard-wired to look for a bean named "transactionManager" by default…
Prashant Kalkar
Working at Sahaj software Solutions, Pune, India.
Updated on June 06, 2022Comments
-
Prashant Kalkar almost 2 years
I am using Spring 3 with Hibernate 3. I am trying to configure Spring declarative transaction, but no matter what I try, Spring transaction is not getting started.
Here is my configuration
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>
I have a class ServiceLocatorImpl which implements ServiceLocator interface
@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"); } ...... } .... }
It seems to me that all my configuration is correct. But when executeService method is called, TransactionSynchronizationManager.isActualTransactionActive() is always returning false.
Please help me solving this problem. Let me know if any more information required.
Update: I have wired the ServiceLocator into one of the other classes, as follows:
@Autowired private ServiceLocator serviceLocator; // ServiceLocator is interface
I am using Spring 3.0.0 version.
executeService() is one the method defined in the ServiceLocator interface. I updated the code to throw exception instead of just logging an error. Following is the stack trace, I don't see any proxy creation in this trace. Please help.
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 [Solved] I got the issue fixed. Before giving the answer as how it was fixed, I need to provide some more information. I am using Spring MVC in my project. The control DispatchServlet is configured in the web.xml. This front controller has a configuration xml file abc-servlet.xml (abc being the servlet name in web.xml). I have other spring configuration files too which are defined as
context-param
inweb.xml
. One of the file isapplicationContext-hibernate.xml
file.I defined the
txManager
and<tx:annotation-driven />
, in theapplicationContext-hibernate.xml
file. Today I was wondering whether @Autowired and @Transactional work with together, so I Google the information, and found this threadThe thread talk about similar problem, and this solves the problem.
I implemented one of the suggestion and added <tx:annotation-driven .../> to my servlet's application context xml and it fixes the problem.
Thinking that I also moved my
<tx:annotation-driven />
into abc-servlet.xml file and it worked.My logs are now shoulding the required messages:
[venice] DEBUG [http-8080-1] 27 Sep 2011 14:24:06,312 ServiceLocatorImpl.logTransactionStatus(100) | ServiceLocator:executeService - Active transaction found
Thanks to everyone for Helping. May be this information will be helpful to someone. I would still like to hear about the explanation as why it was not working earlier.
-
Tomasz Nurkiewicz over 12 yearsIs
executeService()
implementing a method defined inServiceLocator
? Can you throw an exception from this method instead of logging an error and paste the stack trace? I want to see whether the transaction aspect is on the stack. Also please provide the exact Spring version. -
Arun P Johny over 12 yearsCan you show how the method is called? Also can you check what is the instance type of ServiceLocator, is it a proxy instance?
-
Prashant Kalkar over 12 yearsI have updated the question with required stack track. As updated I am injecting the
ServiceLocator
instance in the calling bean.executeService()
is defined inServiceLocator
interface. -
oers over 12 yearsYou can and should post your solution as an answer to this question(which you can accept later).
-
Mukus over 11 yearsWhat was the suggestion? You already had annotation driven transactions. How does moving that help?
-
Rahul Bansal over 9 yearsThanks a lot for this.
-
-
Prashant Kalkar over 12 yearsI am not instantiating the ServiceLocator, instead I am injecting the service locator bean. The calling information is updated in original post.
-
Ryan Stewart over 12 years@user746528: Updated my answer