设为首页 加入收藏

TOP

Spring 多线程的事务处理(三)
2023-09-23 15:44:13 】 浏览:182
Tags:Spring 程的事
tus = newTransactionStatus( definition, transaction, newTransaction, newSynchronization, debug, suspendedResources); prepareSynchronization(status, definition); return status; } // TransactionSynchronizationManager 线程绑定对象的部分处理,不是特别重要 protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) { if (status.isNewSynchronization()) { TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction()); TransactionSynchronizationManager.setCurrentTransactionIsolationLevel( definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ? definition.getIsolationLevel() : null); TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly()); TransactionSynchronizationManager.setCurrentTransactionName(definition.getName()); TransactionSynchronizationManager.initSynchronization(); } }

接下来我们继续查看对于启动事务时的有关处理:

// 开启一个新的事务
private TransactionStatus startTransaction(TransactionDefinition definition, 
                                           Object transaction,
                                           boolean debugEnabled, 
                                           @Nullable SuspendedResourcesHolder suspendedResources) {
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    DefaultTransactionStatus status = newTransactionStatus(
        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
    doBegin(transaction, definition);
    prepareSynchronization(status, definition);
    return status;
}

// 相当于开启事务的 BEGIN 语句
protected void doBegin(Object transaction, TransactionDefinition definition) {
    /*
    	由上文的 doGetTransaction 方法可知当前的 transaction 一定为 DataSourceTransactionObject 类型
    */
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    Connection con = null;

    try {
        /*
        	由于 TransactionSynchronizationManager.getResource(obtainDataSource()) 可能为 null,
        	因此需要对这种情况进行处理,避免为 null
        */
        if (!txObject.hasConnectionHolder() ||
            txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
            Connection newCon = obtainDataSource().getConnection();
            if (logger.isDebugEnabled()) {
                logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
            }
            txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
        }

        // 省略一些不是特别重要的数据库连接和准备的相关代码

        /*
        	到这里就比较关键了,结合上文 doGetTransaction 方法可知,这两者之间是对应的,只要 TransactionSynchronizationManager 绑定的资源对象一致,那么就能够检测到当前执行的事务信息
        */
        if (txObject.isNewConnectionHolder()) {
            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);
    }
}

通过对 doBegindoGetTransaction 方法的分析,我们可以知道,只要 TransactionSynchronizationManager#getResource(Object) 能够拿到同一个线程绑定的资源对象,那么我们就可以将这两个操作合并到一个事务中,并且能够直接复用 Spring 现有的事务处理逻辑!

具体解决方案

通过对 Spring 事务处理的源码分析,我们可以知道,如果希望当前线程执行上下文能够检测到事务的存在,我们只要通过 TransactionSynchronizationManager 绑定一致的事务资源对象即可。为了方便,我们可以直接将线程执行的任务封装到一个新的任务类中,在这个任务类中绑定相关的事务资源即可,对应的任务类如下:

import org.slf4j.Logger;
i
首页 上一页 1 2 3 4 5 6 下一页 尾页 3/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇支持JDK19虚拟线程的web框架,之.. 下一篇Redis面试题

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目