Spring的事務管理入門:編程式事務管理(TransactionTemplate)!!!

轉載 自 http://blog.csdn.net/zq9017197/article/details/6321391java

Spring能夠支持編程式事務和聲明式事務。spring

Spring使用事務管理器,每一個不一樣平臺的事務管理器都實現了接口:PlatformTransactionManagersql

此接口是事務管理的核心,提供了三個須要實現的函數:數據庫

[java] view plain copyapache

print?編程

  1. commit(TransactionStatus status) ;    
  2. getTransaction(TransactionDefinition definition) ;    
  3. rollback(TransactionStatus status) ; 

若是咱們使用的是JDBC來處理事務,那麼這個事務管理器就是DataSourceTransactionManager。oracle

經過Spring文檔查找到這個類,發現其須要DataSource這個類。也就是隻要實現了javax.sql.DataSource這個接口的類,均可以做爲參數傳入到DataSourceTransactionManager。函數

而後,找到 包org.springframework.transaction.support中的 TransactionTemplate。編碼

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

[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. public class TemplateUtils { 
  13. private static Logger logger = Logger.getLogger(TemplateUtils.class); 
  14. private static String oracleDS = "java:OracleDS"; 
  15. private static 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. public static TransactionTemplate getTransactionTemplate() { 
  25.         PlatformTransactionManager txManager = new DataSourceTransactionManager( 
  26.                 dataSource); 
  27. return new TransactionTemplate(txManager); 
  28.     } 
  29. public static JdbcTemplate getJdbcTemplate() { 
  30. return new JdbcTemplate(dataSource); 
  31.     } 
  32. public static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { 
  33. return new NamedParameterJdbcTemplate(dataSource); 
  34.     } 
  35. public static SimpleJdbcTemplate getSimpleJdbcTemplate() { 
  36. return new SimpleJdbcTemplate(dataSource); 
  37.     } 

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. public class Test { 
  14. public void 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. return null; 
  27.             } 
  28.         }); 
  29.     } 
  30. public void m2() throws Exception { 
  31.         TransactionTemplate transactionTemplate = TemplateUtils 
  32.                 .getTransactionTemplate(); 
  33.         transactionTemplate.execute(new TransactionCallbackWithoutResult() { 
  34. protected void doInTransactionWithoutResult(TransactionStatus s) { 
  35. try { 
  36. // 數據庫操做1
  37. // 數據庫操做2
  38.                 } catch (Exception e) { 
  39.                     s.setRollbackOnly(); 
  40.                     e.printStackTrace(); 
  41.                 } 
  42.             } 
  43.         }); 
  44.     } 
  45. public void m3() throws Exception { 
  46.         Context ctx = new InitialContext(); 
  47.         DataSource ds = (DataSource) ctx.lookup("java:OracleDS"); 
  48.         JdbcTemplate jt = new JdbcTemplate(ds); 
  49.         DefaultTransactionDefinition tf = new DefaultTransactionDefinition(); 
  50.         PlatformTransactionManager tm = new DataSourceTransactionManager(ds); 
  51.         TransactionStatus ts = tm.getTransaction(tf); 
  52. try { 
  53. // 數據庫操做1
  54. // 數據庫操做2
  55.             tm.commit(ts); 
  56.         } catch (Exception e) { 
  57.             tm.rollback(ts); 
  58.             e.printStackTrace(); 
  59.         } 
  60.     } 

JdbcUtils

[java] view plain copy

print?

  1. import java.sql.CallableStatement; 
  2. import java.sql.Connection; 
  3. import java.sql.PreparedStatement; 
  4. import java.sql.ResultSet; 
  5. import java.sql.SQLException; 
  6. import java.sql.Savepoint; 
  7. import javax.naming.Context; 
  8. import javax.naming.InitialContext; 
  9. import javax.naming.NamingException; 
  10. import javax.sql.DataSource; 
  11. import org.apache.log4j.Logger; 
  12. public class JdbcUtils { 
  13. private static Logger logger = Logger.getLogger(JdbcUtils.class); 
  14. private static String oracleDS = "java:OracleDS"; 
  15. private static 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. public static Connection getConnection() { 
  25.         Connection conn = null; 
  26. try { 
  27.             conn = dataSource.getConnection(); 
  28.         } catch (SQLException e) { 
  29.             logger.info("獲取數據庫鏈接失敗···", e); 
  30.         } 
  31. return conn; 
  32.     } 
  33. public static void close(Connection conn) { 
  34. if (conn != null) { 
  35. try { 
  36.                 conn.close(); 
  37.             } catch (SQLException e) { 
  38.                 logger.info("釋放數據庫鏈接失敗···", e); 
  39.             } 
  40.         } 
  41.     } 
  42. public static void close(CallableStatement cs) { 
  43. if (cs != null) { 
  44. try { 
  45.                 cs.close(); 
  46.             } catch (SQLException e) { 
  47.                 logger.info("關閉CallableStatement失敗···", e); 
  48.             } 
  49.         } 
  50.     } 
  51. public static void close(PreparedStatement ps) { 
  52. if (ps != null) { 
  53. try { 
  54.                 ps.close(); 
  55.             } catch (SQLException e) { 
  56.                 logger.info("關閉PreparedStatement失敗···", e); 
  57.             } 
  58.         } 
  59.     } 
  60. public static void close(ResultSet rs) { 
  61. if (rs != null) { 
  62. try { 
  63.                 rs.close(); 
  64.             } catch (SQLException e) { 
  65.                 logger.info("關閉ResultSet失敗···", e); 
  66.             } 
  67.         } 
  68.     } 
  69. public static void setAutoCommit(Connection conn, boolean autoCommit) { 
  70. if (conn != null) { 
  71. try { 
  72.                 conn.setAutoCommit(autoCommit); 
  73.             } catch (SQLException e) { 
  74.                 logger.info("設置事務提交方式失敗···", e); 
  75.             } 
  76.         } 
  77.     } 
  78. public static void commit(Connection conn) { 
  79. if (conn != null) { 
  80. try { 
  81.                 conn.commit(); 
  82.             } catch (SQLException e) { 
  83.                 logger.info("提交事務失敗···", e); 
  84.             } 
  85.         } 
  86.     } 
  87. public static void rollback(Connection conn) { 
  88. if (conn != null) { 
  89. try { 
  90.                 conn.rollback(); 
  91.             } catch (SQLException e) { 
  92.                 logger.info("回滾事務失敗···", e); 
  93.             } 
  94.         } 
  95.     } 
  96. public static void rollback(Connection conn, Savepoint sp) { 
  97. if (conn != null) { 
  98. try { 
  99.                 conn.rollback(sp); 
  100.             } catch (SQLException e) { 
  101.                 logger.info("回滾事務失敗···", e); 
  102.             } 
  103.         } 
  104.     } 
相關文章
相關標籤/搜索