Mybatis中事务管理
前置知识
Mysql中的事务级别
- READ UNCOMMITTED (读未提交)
- READ COMMITTED (读已提交)
- REPEATABLE READ (可重复读) InnoDB的默认隔离级别
- SERIABLIZABLE (序列化)
前置源码
TransactionIsolationLevel
package org.apache.ibatis.session;
public enum TransactionIsolationLevel {
NONE(0),READ_COMMITTED(2),READ_UNCOMMITTED(1),REPEATABLE(4),SERIALIZABLE(8);
private final int level;
private TransactionIsolationLevel(int level) {
this.level = level;
}
public int getLevel() {
return this.level;
}
}
所有的源代码都在org.apache.ibatis.transaction包中
Mybatis中的事务管理器分为两类:JDBC类型和MANAGED类型
- JDBC类型
- 应用程序服务器负责事务管理操作,例如提交、回滚等。
- MANAGED类型
- 应用程序服务器负责管理连接生命周期
源码分析
事务处理采用了代理模式,所有的操作都是通过java.sql.Connection完成的
Transaction
package org.apache.ibatis.transaction;
import java.sql.Connection;
import java.sql.SQLException;
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
Integer getTimeOut() throws SQLException;
}
TransactionFactory
package org.apache.ibatis.transaction;
import java.sql.Connection;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.session.TransactionIsolationLevel;
public interface TransactionFactory {
default void setProperties(Properties properties) {}
Transaction newTransaction(Connection var1);
Transaction newTransaction(DataSource var1,TransactionIsolationLevel var2,boolean var3);
}
JdbcTransaction
package org.apache.ibatis.transaction.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionException;
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 autoCommit;
public JdbcTransaction(DataSource ds,TransactionIsolationLevel desiredLevel,boolean desiredAutoCommit) {
this.dataSource = ds;
this.level = desiredLevel;
this.autoCommit = desiredAutoCommit;
}
public JdbcTransaction(Connection connection) {this.connection = connection;}
public Connection getConnection() throws SQLException {
if(this.connection == null) {
this.openConnection();
}
return this.connection();
}
public void commit() throws SQLException {
if(this.connection != null && !this.connection.getAutoCommit()) {
if(log.isDebugEnabled) {
log.debug("Committing JDBC Connection [" + this.connection + "]");
}
this.connection.commit();
}
}
public void rollback() throws SQLException {
if(this.connection != null && !this.connection.getAutoCommit()) {
if(log.isDebugEnabled()) {
log.debug("Rolling back JDBC Connection [" + this.connection + "]");
}
}
}
public void close() throws SQLException {
if(this.connection != null) {
this.resetAutoCommit();
if(log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + this.connection + "]");
}
this.connection.close();
}
}
protected void setDesiredAutoCommit(boolean desiredAutoCommit) {
try {
if (this.connection.getAutoCommit() != desiredAutoCommit) {
if (log.isDebugEnabled()) {
log.debug("Setting autocommit to " + desiredAutoCommit + " on JDBC Connection [" + this.connection + "]");
}
this.connection.setAutoCommit(desiredAutoCommit);
}
} catch (SQLException var3) {
throw new TransactionException("Error configuring AutoCommit. Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: " + desiredAutoCommit + ". Cause: " + var3, var3);
}
}
protected void resetAutoCommit() {
try {
if (!this.connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Resetting autocommit to true on JDBC Connection [" + this.connection + "]");
}
this.connection.setAutoCommit(true);
}
} catch (SQLException var2) {
if (log.isDebugEnabled()) {
log.debug("Error resetting autocommit to true before closing the connection. Cause: " + var2);
}
}
}
protected void openConnecion() throws SQLException {
if(log.isDebugEnabled()) {
log.debug("Opening JDBC Connection");
}
this.connection = this.dataSource.getConnection();
if(this.level != null) {
this.connection.setTransacionIsolation(this.level.getLevel());
}
this.setDesiredAutoCommit(this.autoCommit);
}
public Integer getTimeout() throws SQLException {
return null;
}
}
JdbcTransactionFactory
package org.apache.ibatis.transaction.jdbc;
import java.sql.Connection;
import javax.sql.DataSource;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;
public class JdbcTransactionFactory implements TransactionFactory {
public JdbcTransactionFactory() {}
public Transaction newTransaction(Connection connection) {
return new JdbcTransaction(connection);
}
public Transaction newTransaction(DataSource dataSource,TransactionIsolationLevel level,boolean autoCommit) {
return new JdbcTransaction(dataSource,level,autoCommit);
}
}
ManagedTransaction
package org.apache.ibatis.transaction.managed;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
public class ManagedTransaction implements Transaction {
private static final Log log = LogFactory.getLog(ManagedTransaction.class);
private DataSource dataSource;
private TransactionIsolationLevel level;
private Connection connection;
private final boolean closeConnection;
public ManagedTransaction(Connection connection,boolean closeConnection) {
this.connection = connection;
this.closeConnection = closeConnection;
}
public ManagedTransaction(DataSource dataSource,TransactionIsolationLevel level,boolean closeConnection){
this.dataSource = dataSource;
this.level = level;
this.closeConnection = closeConnection;
}
public Connetion getConnection() throws SQLException {
if(this.connection == null) {
this.openConnection();
}
return this.connection;
}
public void commit() throws SQLException {
}
public void rollback() throws SQLException {
}
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");
}
this.connection = this.dataSource.getConnection();
if (this.level != null) {
this.connection.setTransactionIsolation(this.level.getLevel());
}
}
public Integer getTimeout() throws SQLException {
return null;
}
}
ManagedTransactionFactory
package org.apache.ibatis.transaction.managed;
import java.sql.Connection;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;
public class ManagedTransactionFactory implements TransactionFactory {
private boolean closeConnection = true;
public ManagedTransactionFactory() {
}
public void setProperties(Properties props) {
if (props != null) {
String closeConnectionProperty = props.getProperty("closeConnection");
if (closeConnectionProperty != null) {
this.closeConnection = Boolean.parseBoolean(closeConnectionProperty);
}
}
}
public Transaction newTransaction(Connection conn) {
return new ManagedTransaction(conn, this.closeConnection);
}
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
return new ManagedTransaction(ds, level, this.closeConnection);
}
}