3. Mybatis 事务和Spring事务关系

发布时间 2024-01-09 19:33:14作者: 长城VIP

3. Mybatis 事务和Spring事务关系

Mybatis事务和Spring事务的沟通桥梁就是 TransactionSynchronizationManager。

Mybatis ->TransactionSynchronizationManager

我们先看一下mybatis是如何和TransactionSynchronizationManager对接的。一切都在SqlSessionTemplate这个类的反射逻辑中。

SqlSessionTemplate

SqlSessionTemplate禁用掉了手动事务操作。

public void commit(boolean force) {
    throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
}

public void rollback() {
    throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
获取sqlSession的逻辑

在MybatisAutoConfiguration中创建了SqlSessionTemplate代理DefaultSqlSession以实现DefaultSqlSession的复用。

SqlSessionTemplate是SqlSession的实现之一。其目的主要是适应Spring的容器化环境和Spring 事务。

在SqlSessionTemplate的代理逻辑中会有获取 SqlSession的逻辑。这里会优先从TransactionSynchronizationManager获取一个SqlSession。如果获取不到,再创建一个并注册到TransactionSynchronizationManager中。下次直接用就可以。

public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
    Assert.notNull(sessionFactory, "No SqlSessionFactory specified");
    Assert.notNull(executorType, "No ExecutorType specified");
    SqlSessionHolder holder = (SqlSessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
    SqlSession session = sessionHolder(executorType, holder);
    if (session != null) {
        return session;
    } else {
        LOGGER.debug(() -> {
            return "Creating a new SqlSession";
        });
        session = sessionFactory.openSession(executorType);
        registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);
        return session;
    }
}
判断sqlSession是否支持事务
public static boolean isSqlSessionTransactional(SqlSession session, SqlSessionFactory sessionFactory) {
    Assert.notNull(session, "No SqlSession specified");
    Assert.notNull(sessionFactory, "No SqlSessionFactory specified");
    SqlSessionHolder holder = (SqlSessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
    return holder != null && holder.getSqlSession() == session;
}

DataSourceTransactionManager -> TransactionSynchronizationManager

DataSourceTransactionManager 是Spring事务中事务管理器​PlatformTransactionManager​的一种实现。

PlatformTransactionManager有三个方法分别是:getTransaction、commit、rollback。由于getTransaction最为简洁直观,所以我们单看这个类就可以。

protected Object doGetTransaction() {
	DataSourceTransactionObject txObject = new DataSourceTransactionObject();
	txObject.setSavepointAllowed(isNestedTransactionAllowed());
	ConnectionHolder conHolder =
			(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
	txObject.setConnectionHolder(conHolder, false);
	return txObject;
}