深入理解TransactionTemplate编程式事务

  • Spring可以支持编程式事务和声明式事务。
  • Spring提供的最原始的事务管理方式是基于TransactionDefinitionPlatformTransactionManagerTransactionStatus 编程式事务。
  • TransactionTemplate的编程式事务管理是使用模板方法设计模式对原始事务管理方式的封装。

源码探索

查看 TransactionTemplate.java 源码

public class TransactionTemplate extends DefaultTransactionDefinition implements TransactionOperations, InitializingBean {

    protected final Log logger = LogFactory.getLog(this.getClass());
    private PlatformTransactionManager transactionManager;

    public TransactionTemplate() {
    }

    public TransactionTemplate(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {
        super(transactionDefinition);
        this.transactionManager = transactionManager;
    }

    public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public PlatformTransactionManager getTransactionManager() {
        return this.transactionManager;
    }

    public void afterPropertiesSet() {
        if (this.transactionManager == null) {
            throw new IllegalArgumentException("Property 'transactionManager' is required");
        }
    }

    /*
     *  控制事务管理主要依赖于这个方法
     */
    public <T> T execute(TransactionCallback<T> action) throws TransactionException {
        if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
            return ((CallbackPreferringPlatformTransactionManager)this.transactionManager).execute(this, action);
        } else {
            TransactionStatus status = this.transactionManager.getTransaction(this);

            Object result;
            try {
                result = action.doInTransaction(status);
            } catch (RuntimeException var5) {
                this.rollbackOnException(status, var5);
                throw var5;
            } catch (Error var6) {
                this.rollbackOnException(status, var6);
                throw var6;
            } catch (Exception var7) {
                this.rollbackOnException(status, var7);
                throw new UndeclaredThrowableException(var7, "TransactionCallback threw undeclared checked exception");
            }

            this.transactionManager.commit(status);
            return (T) result;
        }
    }

    private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
        this.logger.debug("Initiating transaction rollback on application exception", ex);

        try {
            this.transactionManager.rollback(status);
        } catch (TransactionSystemException var4) {
            this.logger.error("Application exception overridden by rollback exception", ex);
            var4.initApplicationException(ex);
            throw var4;
        } catch (RuntimeException var5) {
            this.logger.error("Application exception overridden by rollback exception", ex);
            throw var5;
        } catch (Error var6) {
            this.logger.error("Application exception overridden by rollback error", ex);
            throw var6;
        }
    }


}

从源码可以看出TransactionTemplate主要依赖于execute(TransactionCallback<T> action)方法执行事务管理。


再来分析分析execute方法的参数 TransactionCallback

查看接口TransactionCallback.java 发现其仅有一个方法:

public interface TransactionCallback<T> {
    T doInTransaction(TransactionStatus var1);
}

并且有一个抽象类TransactionCallbackWithoutResult实现了接口TransactionCallback

public abstract class TransactionCallbackWithoutResult implements TransactionCallback<Object> {
    public TransactionCallbackWithoutResult() {
    }

    public final Object doInTransaction(TransactionStatus status) {
        this.doInTransactionWithoutResult(status);
        return null;
    }

    protected abstract void doInTransactionWithoutResult(TransactionStatus var1);
}

所以当我们借助TransactionTemplate.execute( ... )执行事务管理的时候,传入的参数有两种选择:
1、TransactionCallback
2、TransactionCallbackWithoutResult
两种区别从命名看就相当明显了,一个是有返回值,一个是无返回值。这个的选择就取决于你是读还是写了。


实现案例

1、在spring配置文件中配置相关TransactionTemplate示例:

    <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 配置 transactionTemplate -->
    <bean id="transactionTemplate"
          class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager">
            <ref bean="transactionManager"/>
        </property>
    </bean>

2、对TransactionCallback进行属性设置(该设置也可以在Spring的配置文件中指定,看个人需求)

 		//设置事务传播属性
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 设置事务的隔离级别,设置为读已提交(默认是ISOLATION_DEFAULT:使用的是底层数据库的默认的隔离级别)
        transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        // 设置是否只读,默认是false
        transactionTemplate.setReadOnly(true);
        // 默认使用的是数据库底层的默认的事务的超时时间
        transactionTemplate.setTimeout(30000);

3、业务代码引用:
(1)借助(TransactionCallback)执行事务管理,既带有返回值:

public Object getObject(String str) {
        /*
         *  执行带有返回值<Object>的事务管理
         */
        transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {

                try {
                      ...
                    //.......   业务代码
                    return new Object();
                } catch (Exception e) {
                    //回滚
                    transactionStatus.setRollbackOnly();
                    return null;
                }
            }
        });
}

(2)借助(TransactionCallbackWithoutResult)执行事务管理,既无返回值:

public void update(String str) {

         /*
         *  执行无返回值的事务管理
         */
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {

                try {

                    // ....  业务代码
                } catch (Exception e){
                    //回滚
                    transactionStatus.setRollbackOnly();
                }

            }
        });
}

猜你喜欢

转载自blog.csdn.net/qq_33404395/article/details/83377382