【问题标题】:What determines if a hibernate session is available outside of @Transactional什么决定了休眠会话在 @Transactional 之外是否可用
【发布时间】:2017-01-09 01:31:40
【问题描述】:

我的 Spring 应用始终使用 @org.springframework.transaction.annotation.Transactional 来打开事务。为了减少与事务相关的不必要开销,我已开始在应用程序中不需要事务的区域中删除其中一些注释。

在此过程中,我注意到已删除 @Transactional 注释的 @Controller 类(在类级别或方法级别)仍然能够使用 SessionFactory#getCurrentSession()。但是,当我从@Service(特别是org.springframework.security.core.userdetails.UserDetailsService 的实现)中删除@Transactional 注释并尝试调用SessionFactory#getCurrentSession() 时,我收到以下信息:

Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
    at com.xxx.datasource.AbstractDAO.getSession(AbstractDAO.java:35)
    at com.xxx.datasource.UserDAO.getLoginUser(UserDAO.java:209)
    at com.xxx.datasource.UserDAO.getLoginUser(UserDAO.java:199)
    at com.xxx.spring.userdetails.service.UserDetailsServiceImpl.loadUserByUsername(UserDetailsServiceImpl.java:24)
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:102)
    ... 49 more

为什么会发生这种情况/是什么决定了SessionFactory#getCurrentSession() 是返回会话还是抛出异常?

(Spring 4.1.9 和 Hibernate 4.3.11)

【问题讨论】:

标签: spring hibernate


【解决方案1】:

在未使用 @Transactional 注释的方法/类中的方法调用 SesssionFactory.getCurrentSession() 将导致异常,因为 TransactionSynchronizationManager.isSynchronizationActive() 将返回 false。它返回 false 因为 @Transaction 方面尚未执行,因此事务同步对于当前线程保持不活动状态。如果它被执行,它将为当前线程激活事务同步。 查看方法:TransactionSynchronizationManager.initSynchronizationTransactionSynchronizationManager.isSynchronizationActive

正如您提到的,您的 @Controller 类工作正常,这可能是因为它们没有执行任何 dao 操作,或者控制器前面的层正在处理事务。

【讨论】:

  • 谢谢。我应该事先自己看一下,但现在我可以确认 OpenSessionInViewInterceptor 是有罪的。我的印象是这种模式只有在请求到达视图层时才打开会话;但事实上,由于它是一个弹簧拦截器,它会在拦截器的preHandle 阶段打开它,然后再点击控制器方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-13
  • 2018-12-31
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
相关资源
最近更新 更多