java事務全解析(五)--Template模式

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

 

這是一個關於Java事務處理的系列文章,請通過以下方式下載github源代碼:

Git clone https://github.com/davenkin/java_transaction_workshop.git

 

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

 

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

  1. public abstract class TransactionTemplate  
  2. {  
  3.     private TransactionManager transactionManager;  
  4.        
  5.     protected TransactionTemplate(DataSource dataSource)  
  6.     {  
  7.         transactionManager = new TransactionManager(dataSource);  
  8.     }  
  9.        
  10.     public void doJobInTransaction()  
  11.     {  
  12.         try  
  13.         {  
  14.             transactionManager.start();  
  15.             doJob();  
  16.             transactionManager.commit();  
  17.         } catch (Exception e)  
  18.         {  
  19.             transactionManager.rollback();  
  20.         } finally  
  21.         {  
  22.             transactionManager.close();  
  23.         }  
  24.     }  
  25.        
  26.     protected abstract void doJob() throws Exception;  
  27. }  
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事務。
  1. public class TransactionTemplateBankService implements BankService  
  2. {  
  3.     private DataSource dataSource;  
  4.     private ConnectionHolderBankDao connectionHolderBankDao;  
  5.     private ConnectionHolderInsuranceDao connectionHolderInsuranceDao;  
  6.       
  7.     public TransactionTemplateBankService(DataSource dataSource)  
  8.     {  
  9.         this.dataSource = dataSource;  
  10.         connectionHolderBankDao = new ConnectionHolderBankDao(dataSource);  
  11.         connectionHolderInsuranceDao = new ConnectionHolderInsuranceDao(dataSource);  
  12.     }  
  13.       
  14.     public void transfer(final int fromId, final int toId, final int amount)  
  15.     {  
  16.         new TransactionTemplate(dataSource)  
  17.         {  
  18.             @Override  
  19.             protected void doJob() throws Exception  
  20.             {  
  21.                 connectionHolderBankDao.withdraw(fromId, amount);  
  22.                 connectionHolderInsuranceDao.deposit(toId, amount);  
  23.             }  
  24.         }.doJobInTransaction();  
  25.     }  
  26. }  
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管理事務的典型方法。



發佈了31 篇原創文章 · 獲贊 15 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章