gpt4 book ai didi

java - 传播设置为 Propagation.NOT_SUPPORTED 时的 Hibernate 和 TransactionRequiredException

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:04:57 26 4
gpt4 key购买 nike

长话短说:

  • 使用 @Transactional(propagation = Propagation.NOT_SUPPORTED) 注释的服务方法
  • Hibernate 5.0.4.Final:一切都按预期工作(方法在没有事务的情况下执行)
  • Hibernate 5.2.5.Final:javax.persistence.TransactionRequiredException:没有事务正在进行被抛出
  • 作为这个问题的测试用例,我创建了一个简单的 maven web 应用程序,代码中所做的唯一更改(从旧工作项目复制粘贴)是 pom.xml 中的 Hibernate 版本提升

问题:

  • 如今在没有事务的情况下执行服务方法的正确方法是什么?

代码片段(以Spring为主框架):

道:

@Repository
public class UrlDaoImpl implements UrlDao {

@Autowired
private SessionFactory sessionFactory;

@Override
public List<Url> getAllUrls() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from Url");
return query.list();
}

}

服务:

@Service
public class UrlServiceImpl implements UrlService {

@Autowired
private UrlDao urlDao;


@Override
@Transactional // THIS WORKS IN NEW HIBERNATE
public List<Url> getAllUrls() {
return urlDao.getAllUrls();
}

@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED) // THIS USED TO WORK BUT NOW THROWS EXCEPTION
public List<Url> getAllUrlsNoTxn() {
return urlDao.getAllUrls();
}

}

Controller :

@Controller
public class HomeController {

@Autowired
private UrlService urlService;

@RequestMapping(value = "/", method = RequestMethod.GET, produces = "text/plain")
public String entryPoint() {

urlService.getAllUrls();
System.out.println("--------------------- ok");
return "ok";
}

@RequestMapping(value = "/no-txn", method = RequestMethod.GET, produces = "text/plain")
public String entryPointNoTxn() {

// EXCEPTION WILL BE THROWN BELOW
urlService.getAllUrlsNoTxn();
System.out.println("--------------------- ok no txn");
return "ok no txn";
}

}

新 Hibernate 中异常的堆栈跟踪:

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

root cause

javax.persistence.TransactionRequiredException: no transaction is in progress
org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3439)
org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1410)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1406)
org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:144)
org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:932)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
com.sun.proxy.$Proxy32.getAllUrlsNT(Unknown Source)
com.example.web.controller.HomeController.entryPointNoTxn(HomeController.java:31)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:220)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

最佳答案

好的,经过几个小时尝试不同的配置(在将此问题发布到 SO 之前),我终于找到了解决方案。

对于新的 Hibernate 版本,如果您想在没有事务的情况下执行方法,则必须在 @Transactional 上声明另一个必需的参数:readOnly = true。所以服务部分的工作示例是:

@Service
public class UrlServiceImpl implements UrlService {

@Autowired
private UrlDao urlDao;


@Override
@Transactional
public List<Url> getAllUrls() {
return urlDao.getAllUrls();
}

@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED) // ADDED READONLY TO WORK IN NEW HIBERNATE VERSIONS
public List<Url> getAllUrlsNoTxn() {
return urlDao.getAllUrls();
}

}

我还通过调用 ((org.hibernate.engine.transaction.internal.TransactionImpl) session.getTransaction()).isActive(); 返回 来确认这适用于调试第一个服务方法(带事务)为 true,第二个服务方法(带 Propagation.NOT_SUPPORTED)为 false

关于java - 传播设置为 Propagation.NOT_SUPPORTED 时的 Hibernate 和 TransactionRequiredException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41778024/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com