为什么在@Transactional注释上“调用事务回滚”

时间:2014-06-30 14:39:33

标签: spring transactions

我对事务REST控制器中的一些异常处理感到困惑。

我有一个管理服务,如下所示:

@Override
public SearchedAdminsEvent search(SearchAdminsEvent searchAdminsEvent) {
    Page<Admin> admins = adminRepository.search(searchAdminsEvent.getSearchTerm(), searchAdminsEvent.getPageRequest());
    if (admins.getTotalElements() == 0) {
        throw new SearchedAdminsNotFoundException(searchAdminsEvent.getSearchTerm());
    } else {
        List<EventAdmin> eventAdmins = EventAdmin.newEventAdminsFrom(admins.getContent()); 
        return new SearchedAdminsEvent(searchAdminsEvent.getSearchTerm(), searchAdminsEvent.getPageRequest(), eventAdmins);
    }
}

我有一个看起来像这样的REST控制器:

@RequestMapping(value = "/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@Transactional(readOnly = true)
@ResponseBody
public ResponseEntity<List<AdminResource>> search(@RequestParam(value = "searchTerm", required = true) String searchTerm, @RequestParam(value = "page", required = true, defaultValue = "0") int page, @RequestParam(value = "size", required = true, defaultValue = "10") int size, UriComponentsBuilder builder) {
    HttpHeaders responseHeaders = new HttpHeaders();
    Pageable pageRequest = buildPageRequest(page, size);
    SearchedAdminsEvent searchedAdminsEvent;
    try {
        searchedAdminsEvent = adminService.search(new SearchAdminsEvent(searchTerm, pageRequest));            
    } catch (SearchedAdminsNotFoundException e) {
        return new ResponseEntity<List<AdminResource>>(responseHeaders, HttpStatus.NOT_FOUND);
    }
    responseHeaders.setLocation(builder.path("/admin/search").queryParam("searchTerm", searchTerm).queryParam("page", page).queryParam("size", size).buildAndExpand(searchedAdminsEvent.getSearchTerm()).toUri());
    List<AdminResource> adminResources = adminResourceAssembler.toResources(searchedAdminsEvent.getEventAdmins());
    ResponseEntity<List<AdminResource>> responseEntity = new ResponseEntity<List<AdminResource>>(adminResources, responseHeaders, HttpStatus.OK);
    return responseEntity;
}

它使用@Transactional(readOnly = true)注释。

如果存在此注释,并且未找到任何搜索项,则会出现以下异常:

2014-06-30 16:22:39,736 DEBUG  [JpaTransactionManager] Participating transaction failed - marking existing transaction as rollback-only 
2014-06-30 16:22:39,736 DEBUG  [JpaTransactionManager] Participating transaction failed - marking existing transaction as rollback-only 
2014-06-30 16:22:39,736 DEBUG  [JpaTransactionManager] Participating transaction failed - marking existing transaction as rollback-only 
2014-06-30 16:22:39,736 DEBUG  [JpaTransactionManager] Setting JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] rollback-only 
2014-06-30 16:22:39,736 DEBUG  [JpaTransactionManager] Setting JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] rollback-only 
2014-06-30 16:22:39,736 DEBUG  [JpaTransactionManager] Setting JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] rollback-only 
2014-06-30 16:22:39,737 DEBUG  [JpaTransactionManager] Initiating transaction commit 
2014-06-30 16:22:39,737 DEBUG  [JpaTransactionManager] Initiating transaction commit 
2014-06-30 16:22:39,737 DEBUG  [JpaTransactionManager] Initiating transaction commit 
2014-06-30 16:22:39,737 DEBUG  [JpaTransactionManager] Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] 
2014-06-30 16:22:39,737 DEBUG  [JpaTransactionManager] Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] 
2014-06-30 16:22:39,737 DEBUG  [JpaTransactionManager] Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] 
2014-06-30 16:22:39,754 DEBUG  [JpaTransactionManager] Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] after transaction 
2014-06-30 16:22:39,754 DEBUG  [JpaTransactionManager] Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] after transaction 
2014-06-30 16:22:39,754 DEBUG  [JpaTransactionManager] Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@1f9bfd9] after transaction 
2014-06-30 16:22:39,755 DEBUG  [EntityManagerFactoryUtils] Closing JPA EntityManager 
2014-06-30 16:22:39,755 DEBUG  [EntityManagerFactoryUtils] Closing JPA EntityManager 
2014-06-30 16:22:39,755 DEBUG  [EntityManagerFactoryUtils] Closing JPA EntityManager 
2014-06-30 16:22:39,760 DEBUG  [ExceptionHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,760 DEBUG  [ExceptionHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,760 DEBUG  [ExceptionHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,762 DEBUG  [ResponseStatusExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,762 DEBUG  [ResponseStatusExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,762 DEBUG  [ResponseStatusExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,763 DEBUG  [DefaultHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,763 DEBUG  [DefaultHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,763 DEBUG  [DefaultHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<java.util.List<com.thalasoft.learnintouch.rest.resource.AdminResource>> com.thalasoft.learnintouch.rest.controller.AdminController.search(java.lang.String,int,int,org.springframework.web.util.UriComponentsBuilder)]: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 
2014-06-30 16:22:39,773 DEBUG  [DispatcherServlet] Could not complete request 
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:522)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    at com.thalasoft.learnintouch.rest.controller.AdminController$$EnhancerByCGLIB$$ebae6d18.search(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:513)
    ... 73 more
2014-06-30 16:22:39,773 DEBUG  [DispatcherServlet] Could not complete request 
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:522)

如果删除注释,则一切正常,响应中包含搜索到的项目。

我想如果没有找到任何搜索项,就会抛出异常,从而触发事务回滚消息。

这是异常处理程序:

@ExceptionHandler(SearchedAdminsNotFoundException.class)
@ResponseBody
public ResponseEntity<ErrorInfo> searchedAdminsNotFoundException(HttpServletRequest request, SearchedAdminsNotFoundException e) {
    String url = request.getRequestURL().toString();
    String errorMessage = localizeErrorMessage("error.admin.search.not.found", new Object[] { e.getSearchTerm() });
    return new ResponseEntity<ErrorInfo>(new ErrorInfo(url, errorMessage), HttpStatus.NOT_FOUND);
}

有没有办法在日志中的某处看到触发事务回滚的内部异常?

我在Spring 3.2.9.RELEASE和Hibernate 3.6.10.Final。

这是根本原因:

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/learnintouch-rest] threw exception [Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly] with root cause
javax.persistence.RollbackException: Transaction marked as rollbackOnly
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:513)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    at com.thalasoft.learnintouch.rest.controller.AdminController$$EnhancerByCGLIB$$b11b3634.search(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

更新:这是我的猜测...异常被捕获,因此它不会显示在日志中。即使捕获到异常,注释也会回滚事务。我对吗 ?在这种情况下,如果使用注释,如何处理,即捕获控制器中的异常?

亲切的问候,

Stephane Eybert

1 个答案:

答案 0 :(得分:1)

您可以将异常传播给控制器,是的,但我选择将服务方法标记为事务性。我想知道为什么你会抛出异常,但我想这也会有效。另一种选择是处理0值来计算管理员(或者你在该查询中计算的任何值)或大于0的值。意思是,您的服务方法执行查询并返回值。如果它为0,那么您为用户准备了适当的网页,否则为其他东西做准备。