1. 程式人生 > >SpringBoot (15)---事務處理

SpringBoot (15)---事務處理

SpringBoot 中的事務處理

 

        前兩章節主要講解了在SpringBoot中關於對資料的操作,本章節將介紹如何進行事務處理。所有的資料訪問技術都離不開事務處理,否則將會造成資料不一致。事務是一系列的動作,一旦其中有一個動作出現錯誤,必須全部回滾,系統將事務中對資料庫的所有已完成的操作全部撤消,滾回到事務開始的狀態,避免出現由於資料不一致而導致的接下來一系列的錯誤。事務的出現是為了確保資料的完整性和一致性,在目前企業級應用開發中,事務管理是必不可少的。

1、SpringBoot事務機制

       事務處理機制都會提供API來開啟事務、提交事務來完成資料操作,或者在發生錯誤的時候回滾資料,避免資料的不完整性、不一致性。

       SpringBoot事務機制實質上就是Spring的事務機制,是採用統一的機制處理來自不同資料訪問技術的事務處理,提供了一個介面 PlatformTransactionManager,已經為不同資料訪問技術可以進行不同的實現,如下表。

資料訪問技術及實現
資料訪問技術 實現類
JDBC DataSourceTransactionManager
JPA JpaTransactionManager
Hibernate HibernateTransactionManager
JDO JdoTransactionManager
分散式事務 JtaTransactionManager

涉及到介面關係如下:

介面PlatformTransactionManager原始碼如下:

 
  1. /*

  2. * Copyright 2002-2012 the original author or authors.

  3. *

  4. * Licensed under the Apache License, Version 2.0 (the "License");

  5. * you may not use this file except in compliance with the License.

  6. * You may obtain a copy of the License at

  7. *

  8. * http://www.apache.org/licenses/LICENSE-2.0

  9. *

  10. * Unless required by applicable law or agreed to in writing, software

  11. * distributed under the License is distributed on an "AS IS" BASIS,

  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  13. * See the License for the specific language governing permissions and

  14. * limitations under the License.

  15. */

  16.  
  17. package org.springframework.transaction;

  18.  
  19. import org.springframework.lang.Nullable;

  20.  
  21. /**

  22. * This is the central interface in Spring's transaction infrastructure.

  23. * Applications can use this directly, but it is not primarily meant as API:

  24. * Typically, applications will work with either TransactionTemplate or

  25. * declarative transaction demarcation through AOP.

  26. *

  27. * <p>For implementors, it is recommended to derive from the provided

  28. * {@link org.springframework.transaction.support.AbstractPlatformTransactionManager}

  29. * class, which pre-implements the defined propagation behavior and takes care

  30. * of transaction synchronization handling. Subclasses have to implement

  31. * template methods for specific states of the underlying transaction,

  32. * for example: begin, suspend, resume, commit.

  33. *

  34. * <p>The default implementations of this strategy interface are

  35. * {@link org.springframework.transaction.jta.JtaTransactionManager} and

  36. * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager},

  37. * which can serve as an implementation guide for other transaction strategies.

  38. *

  39. * @author Rod Johnson

  40. * @author Juergen Hoeller

  41. * @since 16.05.2003

  42. * @see org.springframework.transaction.support.TransactionTemplate

  43. * @see org.springframework.transaction.interceptor.TransactionInterceptor

  44. * @see org.springframework.transaction.interceptor.TransactionProxyFactoryBean

  45. */

  46. public interface PlatformTransactionManager {

  47.  
  48. /**

  49. * Return a currently active transaction or create a new one, according to

  50. * the specified propagation behavior.

  51. * <p>Note that parameters like isolation level or timeout will only be applied

  52. * to new transactions, and thus be ignored when participating in active ones.

  53. * <p>Furthermore, not all transaction definition settings will be supported

  54. * by every transaction manager: A proper transaction manager implementation

  55. * should throw an exception when unsupported settings are encountered.

  56. * <p>An exception to the above rule is the read-only flag, which should be

  57. * ignored if no explicit read-only mode is supported. Essentially, the

  58. * read-only flag is just a hint for potential optimization.

  59. * @param definition TransactionDefinition instance (can be {@code null} for defaults),

  60. * describing propagation behavior, isolation level, timeout etc.

  61. * @return transaction status object representing the new or current transaction

  62. * @throws TransactionException in case of lookup, creation, or system errors

  63. * @throws IllegalTransactionStateException if the given transaction definition

  64. * cannot be executed (for example, if a currently active transaction is in

  65. * conflict with the specified propagation behavior)

  66. * @see TransactionDefinition#getPropagationBehavior

  67. * @see TransactionDefinition#getIsolationLevel

  68. * @see TransactionDefinition#getTimeout

  69. * @see TransactionDefinition#isReadOnly

  70. */

  71. TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;

  72.  
  73. /**

  74. * Commit the given transaction, with regard to its status. If the transaction

  75. * has been marked rollback-only programmatically, perform a rollback.

  76. * <p>If the transaction wasn't a new one, omit the commit for proper

  77. * participation in the surrounding transaction. If a previous transaction

  78. * has been suspended to be able to create a new one, resume the previous

  79. * transaction after committing the new one.

  80. * <p>Note that when the commit call completes, no matter if normally or

  81. * throwing an exception, the transaction must be fully completed and

  82. * cleaned up. No rollback call should be expected in such a case.

  83. * <p>If this method throws an exception other than a TransactionException,

  84. * then some before-commit error caused the commit attempt to fail. For

  85. * example, an O/R Mapping tool might have tried to flush changes to the

  86. * database right before commit, with the resulting DataAccessException

  87. * causing the transaction to fail. The original exception will be

  88. * propagated to the caller of this commit method in such a case.

  89. * @param status object returned by the {@code getTransaction} method

  90. * @throws UnexpectedRollbackException in case of an unexpected rollback

  91. * that the transaction coordinator initiated

  92. * @throws HeuristicCompletionException in case of a transaction failure

  93. * caused by a heuristic decision on the side of the transaction coordinator

  94. * @throws TransactionSystemException in case of commit or system errors

  95. * (typically caused by fundamental resource failures)

  96. * @throws IllegalTransactionStateException if the given transaction

  97. * is already completed (that is, committed or rolled back)

  98. * @see TransactionStatus#setRollbackOnly

  99. */

  100. void commit(TransactionStatus status) throws TransactionException;

  101.  
  102. /**

  103. * Perform a rollback of the given transaction.

  104. * <p>If the transaction wasn't a new one, just set it rollback-only for proper

  105. * participation in the surrounding transaction. If a previous transaction

  106. * has been suspended to be able to create a new one, resume the previous

  107. * transaction after rolling back the new one.

  108. * <p><b>Do not call rollback on a transaction if commit threw an exception.</b>

  109. * The transaction will already have been completed and cleaned up when commit

  110. * returns, even in case of a commit exception. Consequently, a rollback call

  111. * after commit failure will lead to an IllegalTransactionStateException.

  112. * @param status object returned by the {@code getTransaction} method

  113. * @throws TransactionSystemException in case of rollback or system errors

  114. * (typically caused by fundamental resource failures)

  115. * @throws IllegalTransactionStateException if the given transaction

  116. * is already completed (that is, committed or rolled back)

  117. */

  118. void rollback(TransactionStatus status) throws TransactionException;

  119.  
  120. }

2、宣告式事務

         建立在AOP之上的,其本質是對方法前後進行攔截,然後在目標方法開始之前建立或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。宣告式事務最大的優點就是不需要通過程式設計的方式管理事務,這樣就不需要在業務邏輯程式碼中摻雜事務管理的程式碼,只需在配置檔案中做相關的事務規則宣告(或通過基於@Transactional註解的方式),便可以將事務規則應用到業務邏輯中。

      Spring支援宣告式事務,被註解的方法在被呼叫時,Spring開啟一個新的事務,當方法無異常結束後,Spring會提交這個事務。

 
  1. @Transactional

  2. public void insertUser(User user) {

  3. //資料庫表的操作

  4. ……

  5. }

注:

(1)@Transactional是來自org.springframework.transaction.annotation包的。

(2)@Transactional不僅可以註解在方法上,也可以註解在類上。當註解在類上時,意味著此類的所有public方法都是開啟事務的。如果類級別和方法級別同時使用了@Transactional註解,則使用在類級別的註解會過載方法級別的註解。

以下為註解@Transactional原始碼:

(為了縮小所佔篇數,故去掉註釋部分)

 
  1. package org.springframework.transaction.annotation;

  2.  
  3. import java.lang.annotation.Documented;

  4. import java.lang.annotation.ElementType;

  5. import java.lang.annotation.Inherited;

  6. import java.lang.annotation.Retention;

  7. import java.lang.annotation.RetentionPolicy;

  8. import java.lang.annotation.Target;

  9.  
  10. import org.springframework.core.annotation.AliasFor;

  11. import org.springframework.transaction.TransactionDefinition;

  12.  
  13.  
  14. @Target({ElementType.METHOD, ElementType.TYPE})

  15. @Retention(RetentionPolicy.RUNTIME)

  16. @Inherited

  17. @Documented

  18. public @interface Transactional {

  19.  
  20. @AliasFor("transactionManager")

  21. String value() default "";

  22.  
  23. @AliasFor("value")

  24. String transactionManager() default "";

  25.  
  26. Propagation propagation() default Propagation.REQUIRED;

  27.  
  28. Isolation isolation() default Isolation.DEFAULT;

  29.  
  30. int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

  31.  
  32. boolean readOnly() default false;

  33.  
  34. Class<? extends Throwable>[] rollbackFor() default {};

  35.  
  36. String[] rollbackForClassName() default {};

  37.  
  38. Class<? extends Throwable>[] noRollbackFor() default {};

  39.  
  40. String[] noRollbackForClassName() default {};

  41. }

屬性說明如下表:

屬性 型別 描述
value String 可選的限定描述符,指定使用的事務管理器
propagation enum: Propagation 定義事務的生命週期,有REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED,詳細含義可查閱列舉類org.springframework.transaction.annotation.Propagation原始碼。
isolation enum: Isolation 可選的事務隔離級別設定,決定了事務的完整性
readOnly boolean 讀寫或只讀事務,預設讀寫
timeout int (in seconds granularity) 事務超時時間設定
rollbackFor Class物件陣列,必須繼承自Throwable 導致事務回滾的異常類陣列
rollbackForClassName 類名陣列,必須繼承自Throwable 導致事務回滾的異常類名字陣列
noRollbackFor Class物件陣列,必須繼承自Throwable 不會導致事務回滾的異常類陣列
noRollbackForClassName 類名陣列,必須繼承自Throwable 不會導致事務回滾的異常類名字陣列

在SpringBoot中,建議採用註解@Transactional進行事務的控制。