事务指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。对于数据库操作来说是必不可少的。
在Mybatis框架中有二种事务实现,一种是JdbcTransaction,另一种是ManagedTransaction。他们的配置都是通过environment中的transactionManager 标签来配置的。加载过程在
Mybatis源码分析之(二)根据配置文件创建SqlSessionFactory(Configuration的创建过程)中,欢迎大家移步去看看。
<environments default="development">
<environment id="development">
<!-- type为”JDBC”时,使用JdbcTransaction管理事务。
type为”managed”时,使用ManagedTransaction管理事务-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
JdbcTransaction
public class JdbcTransaction implements Transaction {
private static final Log log = LogFactory.getLog(JdbcTransaction.class);
//与数据库的连接
protected Connection connection;
//数据源信息
protected DataSource dataSource;
//表示事务级别
protected TransactionIsolationLevel level;
//是否自动提交
protected boolean autoCommmit;
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
dataSource = ds;
level = desiredLevel;
autoCommmit = desiredAutoCommit;
}
public JdbcTransaction(Connection connection) {
this.connection = connection;
}
@Override
public Connection getConnection() throws SQLException {
if (connection == null) {
openConnection();
}
return connection;
}
@Override
public void commit() throws SQLException {
if (connection != null && !connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Committing JDBC Connection [" + connection + "]");
}
//最终使用的是connection的commit
connection.commit();
}
}
@Override
public void rollback() throws SQLException {
if (connection != null && !connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Rolling back JDBC Connection [" + connection + "]");
}
//最终使用的是connection的rollback
connection.rollback();
}
}
@Override
public void close() throws SQLException {
if (connection != null) {
resetAutoCommit();
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + connection + "]");
}
//最终使用的是connection的close
connection.close();
}
}
}
也就是说JdbcTransaction其实只是在jdbc的connection上面封装了一下,实际使用的其实还是jdbc的事务。、
ManagedTransaction
public class ManagedTransaction implements Transaction {
private static final Log log = LogFactory.getLog(ManagedTransaction.class);
//数据源信息
private DataSource dataSource;
//表示事务级别
private TransactionIsolationLevel level;
//与数据库的连接
private Connection connection;
//关闭链接的标志符
private boolean closeConnection;
public ManagedTransaction(Connection connection, boolean closeConnection) {
this.connection = connection;
this.closeConnection = closeConnection;
}
public ManagedTransaction(DataSource ds, TransactionIsolationLevel level, boolean closeConnection) {
this.dataSource = ds;
this.level = level;
this.closeConnection = closeConnection;
}
@Override
public Connection getConnection() throws SQLException {
if (this.connection == null) {
//打开链接
openConnection();
}
return this.connection;
}
//commit不做任何处理
@Override
public void commit() throws SQLException {
// Does nothing
}
//rollback不做任何处理
@Override
public void rollback() throws SQLException {
// Does nothing
}
@Override
public void close() throws SQLException {
if (this.closeConnection && this.connection != null) {
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + this.connection + "]");
}
this.connection.close();
}
}
protected void openConnection() throws SQLException {
if (log.isDebugEnabled()) {
log.debug("Opening JDBC Connection");
}
//通过dataSource获取链接
this.connection = this.dataSource.getConnection();
if (this.level != null) {
this.connection.setTransactionIsolation(this.level.getLevel());
}
}
}
Mybatis不再控制会话的事务,而是让容器来管理transaction的整个生命周期 。
因为ManagedTransaction的commit和rollback没有任何实现,若你是单用了Mybatis一个框架,那么使用ManagedTransaction作为事务实现,那么当我们无法将一个数据库操作过程,作为一个事务提交上去。因为ManagedTransaction里commit实现为空。