1. 程式人生 > >springmvc事務管理詳解

springmvc事務管理詳解

spring可以支援程式設計式事務和宣告式事務。

Spring使用事務管理器,每個不同平臺的事務管理器都實現了介面:PlatformTransactionManager

此介面是事務管理的核心,提供了三個需要實現的函式:

[java] view plain copy  print?
  1. commit(TransactionStatus status) ;     
  2. getTransaction(TransactionDefinition definition) ;     
  3. rollback(TransactionStatus status) ;  

如果我們使用的是JDBC來處理事務,那麼這個事務管理器就是DataSourceTransactionManager。

通過Spring文件查詢到這個類,發現其需要DataSource這個類。也就是隻要實現了javax.sql.DataSource這個介面的類,都可以作為引數傳入到DataSourceTransactionManager。

 然後,找到 包org.springframework.transaction.support中的 TransactionTemplate。

發現TransactionTemplate中有一個重要的方法:

[java]
 view plain copy  print?
  1. execute(TransactionCallback action) ;  

就是利用這個方法,我們可以在這個方法中新增事務。

這個方法需要傳入引數 TransactionCallback。

TransactionCallback,顧名思義,就是事務回撥然後查到TransactionCallback。

發現這是一個介面(這也必須是介面,因為任務都是自己具體定義的)

裡面只有一個方法:

[java] view plain copy  print?
  1. doInTransaction(TransactionStatus status) ;   

很明顯,就是在一個事務中需要做的事情都包括這這個方法中了。

而這個doInTransaction 又傳入了一個引數,這次是 TransactionStatus,繼續顧名思義,也就是事務狀態。

查詢下去,這個 TransactionStatus 還是一個介面。 看看這個介面定義了哪些服務(方法):

[java] view plain copy  print?
  1. hasSavepoint() ;  
  2. isCompleted() ;    
  3. isNewTransaction() ;  
  4. setRollbackOnly() ;  

當需要回滾的時候,需要在呼叫 setRoolbackOnly(); 就OK了。

好了,走了這麼久,現在就來簡單總結一下程式設計式事務管理。

首先: 因為我們使用的是特定的平臺,所以,我們需要建立一個合適我們的平臺事務管理PlateformTransactionManager。如果使用的是JDBC的話,就用DataSourceTransactionManager。注意需要傳入一個DataSource,這樣,平臺才知道如何和資料庫打交道。

第二: 為了使得平臺事務管理器對我們來說是透明的,就需要使用 TransactionTemplate。使用TransactionTemplat需要傳入一個 PlateformTransactionManager 進入,這樣,我們就得到了一個 TransactionTemplate,而不用關心到底使用的是什麼平臺了。

第三: TransactionTemplate 的重要方法就是 execute 方法,此方法就是呼叫 TransactionCallback 進行處理。

也就是說,實際上我們需要處理的事情全部都是在 TransactionCallback 中編碼的。

第四: 也就是 TransactionCallback 介面,我們可以定義一個類並實現此介面,然後作為 TransactionTemplate.execute 的引數。把需要完成的事情放到 doInTransaction中,並且傳入一個 TransactionStatus 引數。此引數是來呼叫回滾的。

也就是說 ,PlateformTransactionManager 和 TransactionTemplate 只需在程式中定義一次,而TransactionCallback 和 TransactionStatus 就要針對不同的任務多次定義了。

這就是Spring的程式設計式事務管理。下面貼出例子程式碼:

TemplateUtils

[java] view plain copy  print?
  1. import javax.naming.Context;  
  2. import javax.naming.InitialContext;  
  3. import javax.naming.NamingException;  
  4. import javax.sql.DataSource;  
  5. import org.apache.log4j.Logger;  
  6. import org.springframework.jdbc.core.JdbcTemplate;  
  7. import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;  
  8. import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;  
  9. import org.springframework.jdbc.datasource.DataSourceTransactionManager;  
  10. import org.springframework.transaction.PlatformTransactionManager;  
  11. import org.springframework.transaction.support.TransactionTemplate;  
  12. publicclass TemplateUtils {  
  13.     privatestatic Logger logger = Logger.getLogger(TemplateUtils.class);  
  14.     privatestatic String oracleDS = "<a href="http://lib.csdn.net/base/17" class='replace_word' title="Java EE知識庫" target='_blank' style='color:#df3434; font-weight:bold;'>Java</a>:OracleDS";
  15.     privatestatic DataSource dataSource = null;  
  16.     static {  
  17.         try {  
  18.             Context context = new InitialContext();  
  19.             dataSource = (DataSource) context.lookup(oracleDS);  
  20.         } catch (NamingException e) {  
  21.             logger.info("查詢資料來源失敗···", e);  
  22.         }  
  23.     }  
  24.     publicstatic TransactionTemplate getTransactionTemplate() {  
  25.         PlatformTransactionManager txManager = new DataSourceTransactionManager(  
  26.                 dataSource);  
  27.         returnnew TransactionTemplate(txManager);  
  28.     }  
  29.     publicstatic JdbcTemplate getJdbcTemplate() {  
  30.         returnnew JdbcTemplate(dataSource);  
  31.     }  
  32.     publicstatic NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {  
  33.         returnnew NamedParameterJdbcTemplate(dataSource);  
  34.     }  
  35.     publicstatic SimpleJdbcTemplate getSimpleJdbcTemplate() {  
  36.         returnnew SimpleJdbcTemplate(dataSource);  
  37.     }  
  38. }  

Test

[java] view plain copy  print?
  1. import javax.naming.Context;  
  2. import javax.naming.InitialContext;  
  3. import javax.sql.DataSource;  
  4. import org.springframework.jdbc.core.JdbcTemplate;  
  5. import org.springframework.jdbc.datasource.DataSourceTransactionManager;  
  6. import org.springframework.transaction.PlatformTransactionManager;  
  7. import org.springframework.transaction.TransactionStatus;  
  8. import org.springframework.transaction.support.DefaultTransactionDefinition;  
  9. import org.springframework.transaction.support.TransactionCallback;  
  10. import org.springframework.transaction.support.TransactionCallbackWithoutResult;  
  11. import org.springframework.transaction.support.TransactionTemplate;  
  12. @SuppressWarnings("all")  
  13. publicclass Test {  
  14.     publicvoid m1() throws Exception {  
  15.         TransactionTemplate transactionTemplate = TemplateUtils  
  16.                 .getTransactionTemplate();  
  17.         Object object = transactionTemplate.execute(new TransactionCallback() {  
  18.             public Object doInTransaction(TransactionStatus status) {  
  19.                 try {  
  20.                     // 資料庫操作1
  21.                     // 資料庫操作2
  22.                 } catch (Exception e) {  
  23.                     status.setRollbackOnly();  
  24.                     e.printStackTrace();  
  25.                 }  
  26.                 returnnull;  
  27.             }