Could not obtain transaction-synchronized Session for current thread

/ Spring / 没有评论 / 462浏览

最近在跑自己写的spring的测试时,遇到一个异常,如下:

Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
	at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:133)
	at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:699)

在网上搜索得到结果的都不适合我所遇到的场景,于是通过自己调试发现根源问题在org.springframework.transaction.support.TransactionSynchronizationManager#isSynchronizationActive方法,其内容为:

	/**
	 * Return if transaction synchronization is active for the current thread.
	 * Can be called before register to avoid unnecessary instance creation.
	 * @see #registerSynchronization
	 */
	public static boolean isSynchronizationActive() {
		return (synchronizations.get() != null);
	}

该方法返回了false,从而最终导致前面的异常。再仔细查看,是由于


	private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
			new NamedThreadLocal<Set<TransactionSynchronization>>("Transaction synchronizations");

该ThreadLocal变量未set值导致,再仔细观察,该类中还有个方法TransactionSynchronizationManager.initSynchronization(),其源码如下:

	/**
	 * Activate transaction synchronization for the current thread.
	 * Called by a transaction manager on transaction begin.
	 * @throws IllegalStateException if synchronization is already active
	 */
	public static void initSynchronization() throws IllegalStateException {
		if (isSynchronizationActive()) {
			throw new IllegalStateException("Cannot activate transaction synchronization - already active");
		}
		logger.trace("Initializing transaction synchronization");
		synchronizations.set(new LinkedHashSet<TransactionSynchronization>());
	}

这样看来自己的测试代码应该是比主程序少了些东西,导致没有主动调用它所导致的, 于是我就在spring启动时必须加载的代码中加入了如下代码:


TransactionSynchronizationManager.initSynchronization();

再次重新启动程序,问题不再出现。