我们知道Spring对事务的管理可以通过两种方式去实现,声明式事务,编程式事务,那么spring在底层是如何保证方法的事务性的呢?
首先,我们要理解SqlsessionTemplate的实现方式,上篇文章里已经点出了,通过SqlSession来处理,那么当事务性方法里多个数据库操作的时候,会把第一个初始化的Sqlsession放到ThreadLocal里,这样后续的操作直接使用ThreadLocal里的Sqlsession,那个这个方法的事务性操作都由一个Sqlsession来控制,提交或者回滚。对于非事务性的方法,每次对数据库的操作都会生成一个SqlSession.
SqlSession是由SqlsessionFactory来统一生成的,如下代码所示:
private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
try {
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException e) {
// Failover to true, as most poor drivers
// or databases won't support transactions
autoCommit = true;
}
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
我们注意到DefaultSqlsession由一个重要的参数就是Executor,Executor有一个重要的参数Transaction。
Excutor里面封装了具体的增删改查的方法
Transaction类里大致方法如下:
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
Integer getTimeout() throws SQLExceptionn
所以Sqlsession的事务操作,实际上是由Transaction来操作的。