深入理解TransactionTemplate編程式事務


 Spring可以支持編程式事務和聲明式事務。
 Spring提供的最原始的事務管理方式是基於TransactionDefinition、PlatformTransactionManager、TransactionStatus 編程式事務。
 而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();
                }
            }
        });
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM