在Mybatis的配置文件中可以配置事务管理方式如下:
说明:
(1)type为"JDBC"时,使用JdbcTransaction管理事务。
(2)type为"managed"时,使用ManagedTransaction管理事务(也就是交由外部容器管理)
mybatis的事务是由TransactionFactory创建的,利用典型的简单工厂模式来创建Transaction,如下图:
说明:
Transaction:封装事务管理方法的接口
TransactionFactory:抽象事务工厂生产方法
JdbcTransactionFactory:实现TransactionFactory接口,用于生产JdbcTransaction的工厂类
ManagedTransactionFactory:实现TransactionFactory接口,用于生产ManagedTransaction的工厂类
JdbcTransaction:实现Transaction接口,只是对事务进行了一层包装、实际调用数据库连接Connection的事务管理方法
ManagedTransaction:实现Transaction没有对数据库连接做任何事务处理、交由外部容器管理
第一步:解析配置文件的transactionManager节点。
private void environmentsElement(XNode context) throws Exception {
//只关注事务部分...
TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
...
}
private TransactionFactory transactionManagerElement(XNode context) throws Exception {
if (context != null) {
String type = context.getStringAttribute("type");
Properties props = context.getChildrenAsProperties();
TransactionFactory factory = (TransactionFactory) resolveClass(type).newInstance();
factory.setProperties(props);
return factory;
}
throw new BuilderException("Environment declaration requires a TransactionFactory.");
}
注意:两种事务工厂已经在mybatis初始化的时候完成了注册:
typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
第二步:利用反射机制生成具体的的factory,此处以JdbcTransactionFactory为例,查看一下JdbcTransactionFactory的源码:
public class JdbcTransactionFactory implements TransactionFactory {
public void setProperties(Properties props) {
}
public Transaction newTransaction(Connection conn) {
return new JdbcTransaction(conn);
}
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
return new JdbcTransaction(ds, level, autoCommit);
}
}
说明:
在反射过程中,JdbcTransactionFactory默认无参构造方法被调用
第三步:获取具体类型的事务,以JdbcTransaction为例。
public Transaction newTransaction(Connection conn) {
return new JdbcTransaction(conn);
}
说明:
JdbcTransaction是通过Connection来创建具体的实例
第四步:事务的底层实现。以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;
}
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();
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + connection + "]");
}
connection.close();
}
}
protected void setDesiredAutoCommit(boolean desiredAutoCommit) {
try {
if (connection.getAutoCommit() != desiredAutoCommit) {
connection.setAutoCommit(desiredAutoCommit);
}
} catch (SQLException e) {
throw new TransactionException("Error configuring AutoCommit. "
+ "Your driver may not support getAutoCommit() or setAutoCommit(). "
+ "Requested setting: " + desiredAutoCommit + ". Cause: " + e, e);
}
}
protected void resetAutoCommit() {
try {
if (!connection.getAutoCommit()) {
connection.setAutoCommit(true);
}
} catch (SQLException e) {
log.debug("Error resetting autocommit to true "
+ "before closing the connection. Cause: " + e);
}
}
protected void openConnection() throws SQLException {
connection = dataSource.getConnection();
if (level != null) {
connection.setTransactionIsolation(level.getLevel());
}
setDesiredAutoCommit(autoCommmit);
}
}
从源码中可知,JdbcTransaction如何管理事务的,是通过封装调用DataSource获取connection来实现的。
关注微信公众号获取更多VSCode编程信息,定时发布干货文章
全部评论