MyBatis Transaction 事务接口
1、MyBatis事务介绍
Mybatis管理事务是分为两种方式:
(1)使用JDBC的事务管理机制,就是利用java.sql.Connection
对象完成对事务的提交。
(2)使用MANAGED的事务管理机制,此时MyBatis自身不会去实现事务管理,而是让程序的容器(JBOSS、WebLogic)来实现对事务的管理
2、MyBatis Transaction 事务接口
Mybatis提供了一个事务接口Transaction
以及两个实现类jdbcTransaction
和ManagedTransaction
。
2.1、Transaction接口
Transaction接口提供的抽象方法有获取数据库连接getConnection,提交事务commit,回滚事务rollback和关闭连接close。
源码如下:
public interface Transaction
{
//获得数据库连接
Connection getConnection() throws SQLException;
//提交
void commit() throws SQLException;
//回滚
void rollback() throws SQLException;
//关闭连接
void close() throws SQLException;
}
2.2、JdbcTransaction类
JdbcTransaction类通过使用JDBC提供的方式来管理事务,通过Connection提供的事务管理方法来进行事务管理。
源码如下:
public class JdbcTransaction implements Transaction
{
/* 连接**/
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;
}
public Connection getConnection() throws SQLException
{
if (connection == null)
{
openConnection();
}
//返回连接
return connection;
}
public void commit() throws SQLException
{
if (connection != null && !connection.getAutoCommit())
{
//连接提交
connection.commit();
}
}
public void rollback() throws SQLException
{
if (connection != null && !connection.getAutoCommit())
{
//操作回滚
connection.rollback();
}
}
public void close() throws SQLException
{
if (connection != null)
{
resetAutoCommit();
//关闭连接
connection.close();
}
}
protected void setDesiredAutoCommit(boolean desiredAutoCommit)
{
try
{
//事务提交状态不一致时修改
if (connection.getAutoCommit() != desiredAutoCommit)
{
connection.setAutoCommit(desiredAutoCommit);
}
}
catch (SQLException e)
{
throw new TransactionException("Error configuring AutoCommit.", e);
}
}
protected void resetAutoCommit()
{
try
{
if (!connection.getAutoCommit())
{
connection.setAutoCommit(true);
}
}
catch (SQLException e)
{
}
}
protected void openConnection() throws SQLException
{
connection = dataSource.getConnection();
if (level != null)
{
connection.setTransactionIsolation(level.getLevel());
}
setDesiredAutoCommit(autoCommmit);
}
}
2.3、ManagedTransaction类
ManagedTransaction类通过容器来进行事务管理,所有它对事务提交和回滚并不会做任何操作。
源码如下:
public class ManagedTransaction implements Transaction
{
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;
}
public Connection getConnection() throws SQLException
{
if (this.connection == null)
{
openConnection();
}
return this.connection;
}
//提交操作
public void commit() throws SQLException
{
// Does nothing
}
//回滚操作
public void rollback() throws SQLException
{
// Does nothing
}
public void close() throws SQLException
{
if (this.closeConnection && this.connection != null)
{
//关闭连接
this.connection.close();
}
}
protected void openConnection() throws SQLException
{
this.connection = this.dataSource.getConnection();
if (this.level != null)
{
this.connection.setTransactionIsolation(this.level.getLevel());
}
}
}
总之,Mybatis的事务管理机制还是比较简单的,其并没有做过多的操作,只是封装一下方便别人调用而已。
3、SpringManagedTransaction 类
当Spring与Mybatis一起使用时,Spring提供了一个实现类SpringManagedTransaction
。它其实也是通过使用JDBC来进行事务管理的,当Spring的事务管理有效时,不需要操作commit、rollback、close,Spring事务管理会自动帮我们完成。
源码如下:
public class SpringManagedTransaction implements Transaction
{
private final DataSource dataSource;
private Connection connection;
private boolean isConnectionTransactional;
private boolean autoCommit;
public SpringManagedTransaction(DataSource dataSource)
{
notNull(dataSource, "No DataSource specified");
this.dataSource = dataSource;
}
public Connection getConnection() throws SQLException
{
if (this.connection == null)
{
openConnection();
}
return this.connection;
}
private void openConnection() throws SQLException
{
this.connection = DataSourceUtils.getConnection(this.dataSource);
this.autoCommit = this.connection.getAutoCommit();
this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);
}
public void commit() throws SQLException
{
if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit)
{
this.connection.commit();
}
}
public void rollback() throws SQLException
{
if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit)
{
this.connection.rollback();
}
}
public void close() throws SQLException
{
DataSourceUtils.releaseConnection(this.connection, this.dataSource);
}
}