事务管理器的具体实现DataSourceTransactionManager

        前文我们讨论了抽象的TransactionManager实现AbstractPlatformTransactionManager,其定义诸多模板方法,主要目的是处理事务的传播行为,在合适的时机挂起当前事务,本事务完成后重放挂起的事务,参见AbstractPlatformTransactionManager解析,而DataSourceTransactionManager作为抽象类的具体实现,就是实现了对与DB数据源如何创建事务,提交事务等等,也就是对抽象类中抽象方法的实现。

  1. doGetTransaction()
  2. isExistingTransaction()判断当前是否存在事务
  3. doBegin()开启事务模板方法
  4. doSuspend()挂起事务扩展逻辑
  5. doResume()恢复事务扩展逻辑
  6. doCommit()具体如何提交
  7. doRollback()具体如何回滚

顾明思意,这个具体实现类主要针对关系型数据库而实现,其字段属性中就包含dataSource字段。

public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
		implements ResourceTransactionManager, InitializingBean {

	@Nullable
	private DataSource dataSource; // 数据源连接池,可获取具体的物理连接,如mysql连接
	private boolean enforceReadOnly = false;
 
	public DataSourceTransactionManager() {
		setNestedTransactionAllowed(true);
	}
	public DataSourceTransactionManager(DataSource dataSource) {
		this();
		setDataSource(dataSource);
		afterPropertiesSet();
	}
}

对抽象方法的实现

// 获取具体的事务对象
@Override
protected Object doGetTransaction() {
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    txObject.setSavepointAllowed(isNestedTransactionAllowed());
    ConnectionHolder conHolder =
        (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
}

@Override
protected boolean isExistingTransaction(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}

@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
    // 新建事务对象
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    Connection con = null;

    try {
        if (!txObject.hasConnectionHolder() ||
            txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
            
            //从连接池中获取连接,并封装到当前事务对象中
            Connection newCon = obtainDataSource().getConnection();
            txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
        }

        txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
        con = txObject.getConnectionHolder().getConnection();

        Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
        // 隔离级别
        txObject.setPreviousIsolationLevel(previousIsolationLevel);
        // 是否只读
        txObject.setReadOnly(definition.isReadOnly());

        // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
        // so we don't want to do it unnecessarily (for example if we've explicitly
        // configured the connection pool to set it already).
        if (con.getAutoCommit()) {
            txObject.setMustRestoreAutoCommit(true);
            // 设置手动提交
            con.setAutoCommit(false);
        }
		// 将事务定义信息配置到具体的物理连接上(只读等)
        prepareTransactionalConnection(con, definition);
        txObject.getConnectionHolder().setTransactionActive(true);

        int timeout = determineTimeout(definition);
        if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
            txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
        }

        // Bind the connection holder to the thread.
        if (txObject.isNewConnectionHolder()) {
            
            // 绑定连接到当前线程ThreadLocalMap
            TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
        }
    } catch (Throwable ex) {
        if (txObject.isNewConnectionHolder()) {
            DataSourceUtils.releaseConnection(con, obtainDataSource());
            txObject.setConnectionHolder(null, false);
        }
        throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
    }
}

// 具体的挂起当前事务逻辑
@Override
protected Object doSuspend(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    txObject.setConnectionHolder(null);
    // 将连接从ThreadLocalMap中移除并返回
    return TransactionSynchronizationManager.unbindResource(obtainDataSource());
}

// 将连接绑定到线程的ThreadLocalMap中
@Override
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
    // 恢复挂起的连接(事务)
    TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);
}

@Override
protected void doCommit(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    try {
        // 调用物理连接的提交
        con.commit();
    }
    catch (SQLException ex) {
        throw translateException("JDBC commit", ex);
    }
}

// 具体的回滚方法,调用物理连接的回滚
@Override
protected void doRollback(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    try {
        con.rollback();
    }
    catch (SQLException ex) {
        throw translateException("JDBC rollback", ex);
    }
}

// 设置事务只读
protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition)
    throws SQLException {

    if (isEnforceReadOnly() && definition.isReadOnly()) {
        try (Statement stmt = con.createStatement()) {
            stmt.executeUpdate("SET TRANSACTION READ ONLY");
        }
    }
}

具体事务对象类

private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {

    private boolean newConnectionHolder;
    private boolean mustRestoreAutoCommit;

    public void setConnectionHolder(@Nullable ConnectionHolder connectionHolder, boolean newConnectionHolder) {
        super.setConnectionHolder(connectionHolder);
        this.newConnectionHolder = newConnectionHolder;
    }

    public void setRollbackOnly() {
        getConnectionHolder().setRollbackOnly();
    }

    @Override
    public boolean isRollbackOnly() {
        return getConnectionHolder().isRollbackOnly();
    }

    @Override
    public void flush() {
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationUtils.triggerFlush();
        }
    }
}

//
public abstract class JdbcTransactionObjectSupport implements SavepointManager, SmartTransactionObject {
    @Nullable
	private ConnectionHolder connectionHolder;
	@Nullable
	private Integer previousIsolationLevel;
	private boolean readOnly = false;
	private boolean savepointAllowed = false;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值