Java事務(5)——Template模式

本系列上一篇文章中,我們講到了使用TransactionManger和ConnectionHolder完成線程安全的事務管理,在本篇中,我們將在此基礎上引入Template模式進行事務管理。

 

  Template模式大家應該都很熟悉,比如Spring就提供了許多Template,像JdbcTemplate和JmsTemplate等。Template模式的基本思想是:在超類裏將完成核心功能的方法聲明爲抽象方法,留給子類去實現,而在超類中完成一些通用操作,比如JMS的Session的建立和數據庫事務的準備工作等。

 

  在本篇文章中,我們使用一個Template類來幫助管理事務,定義TransactionTemplate類如下:

複製代碼
package davenkin.step4_transaction_template;

import davenkin.step3_connection_holder.TransactionManager;
import javax.sql.DataSource;

public abstract class TransactionTemplate
{
    private TransactionManager transactionManager;

    protected TransactionTemplate(DataSource dataSource)
    {
        transactionManager = new TransactionManager(dataSource);
    }

    public void doJobInTransaction()
    {
        try
        {
            transactionManager.start();
            doJob();
            transactionManager.commit();
        } catch (Exception e)
        {
            transactionManager.rollback();
        } finally
        {
            transactionManager.close();
        }
    }

    protected abstract void doJob() throws Exception;
}
複製代碼

 

  在TransactionTemplate類中定義一個doJobInTransaction方法,在該方法中首先使用TransactionManager開始事務,然後調用doJob方法完成業務功能,doJob方法爲抽象方法,完成業務功能的子類應該實現該方法,最後,根據doJob方法執行是否成功決定commit事務或是rollback事務。

 

  然後定義使用TransactionTemplate的TransactionTemplateBankService:

複製代碼
package davenkin.step4_transaction_template;

import davenkin.BankService;
import davenkin.step3_connection_holder.ConnectionHolderBankDao;
import davenkin.step3_connection_holder.ConnectionHolderInsuranceDao;
import javax.sql.DataSource;

public class TransactionTemplateBankService implements BankService
{
    private DataSource dataSource;
    private ConnectionHolderBankDao connectionHolderBankDao;
    private ConnectionHolderInsuranceDao connectionHolderInsuranceDao;

    public TransactionTemplateBankService(DataSource dataSource)
    {
        this.dataSource = dataSource;
        connectionHolderBankDao = new ConnectionHolderBankDao(dataSource);
        connectionHolderInsuranceDao = new ConnectionHolderInsuranceDao(dataSource);
    }

    public void transfer(final int fromId, final int toId, final int amount)
    {
        new TransactionTemplate(dataSource)
        {
            @Override
            protected void doJob() throws Exception
            {
                connectionHolderBankDao.withdraw(fromId, amount);
                connectionHolderInsuranceDao.deposit(toId, amount);
            }
        }.doJobInTransaction();
    }
}
複製代碼

 

  在TransactionTemplateBankService的transfer方法中,我們創建了一個匿名的TtransactionTemplate類,並且實現了doJob方法,在doJob方法中調用兩個DAO完成業務操作,然後調用調用TransactionTemplateBankService的doJobInTransaction方法。

 

  由於TransactionTemplate只是對上一篇文章中事務處理的一層封裝,故TransactionManager和兩個DAO類都保持和上一篇中的一樣,此時他們都使用SingleThreadConnectionHolder獲得Connection,故事務處理成功。

 

  在下一篇文章中,我們會講到使用Java的動態代理來完成事務處理,這也是Spring管理事務的典型方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章