transactiontemplate詳解

一、transactiontemplate用法

TransactionTemplate 是 Spring 的一個功能強大的事務管理工具類。它為我們帶來了很多便利,通過它我們可以不用再關心事務的傳播性和隔離級別等一系列細節,而是把精力放在業務邏輯的實現上。使用 TransactionTemplate 可以讓代碼更加簡潔、優雅和安全。

使用 TransactionTemplate 的方式非常簡單,只需要在需要進行事務管理的代碼塊外層套一個 execute 方法就可以開啟事務了,這個方法會隱式的開啟一個事務,如果 execute 方法內部的代碼執行成功,則事務會自動提交,否則事務會自動回滾。

  public interface TransactionTemplate {
      <T> T execute(TransactionCallback<T> action) throws TransactionException;
  }

其中,TransactionCallback 介面的 doInTransaction 方法就是需要進行事務管理的代碼塊。這個介面包含一個泛型參數 T,表示執行結果的類型,這個類型的值會被 execute 方法返回。

  public interface TransactionCallback<T> {
      T doInTransaction(TransactionStatus status);
  }

通常情況下,我們需要在 doInTransaction 方法內部寫上具體的業務邏輯代碼。例如,在下面的示例中,我們採用了匿名內部類方式實現了一個 TransactionCallback

  public class UserServiceImpl implements UserService {

      private final TransactionTemplate transactionTemplate;

      public UserServiceImpl(DataSource dataSource) {
          this.transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
      }

      public void transferMoney(String fromUser, String toUser, int money) {
          transactionTemplate.execute(new TransactionCallback<Void>() {
              public Void doInTransaction(TransactionStatus status) {
                  try {
                      User from = userDao.findByName(fromUser);
                      User to = userDao.findByName(toUser);
                      from.setMoney(from.getMoney() - money);
                      to.setMoney(to.getMoney() + money);
                      userDao.update(from);
                      userDao.update(to);
                      return null;
                  } catch (Exception e) {
                      status.setRollbackOnly();
                      throw e;
                  }
              }
          });
      }
  }

在上面的 transferMoney 方法中,我們使用了 TransactionTemplate 來控制事務,從而實現了轉賬的功能。事務的傳播性、超時時間、隔離級別等信息都可以在 TransactionTemplate 中進行配置。

二、transactionTemplate 回滾

事務處理中,有時候我們需要手動回滾一個事務,例如某些必要的校驗未通過,或者拋出了某個異常。 TransactionTemplate 為我們提供了很方便的事務回滾機制。

要實現事務回滾,我們只需要在 TransactionCallbackdoInTransaction 方法內部拋出一個運行時異常即可,例如下面的示例:

  transactionTemplate.execute(new TransactionCallback<Void>() {
      public Void doInTransaction(TransactionStatus status) {
          try {
              [...]

              if (someCheckFailed) {
                  throw new RuntimeException("校驗未通過,回滾事務");
              }

              [...]
          } catch (Exception e) {
              status.setRollbackOnly();
              throw e;
          }
      }
  });

在這個示例中,如果檢測到校驗未通過,就會拋出一個運行時異常,這時候 TransactionTemplate 會自動回滾事務,保證不會出現數據不一致等問題。

三、transactionTemplate 拿返回值

在實際業務應用中,我們不僅需要對事務進行控制,還需要返回一些數據給調用者。 TransactionTemplate 也為我們提供了很方便的方式來拿到執行結果。

TransactionCallbackdoInTransaction 方法中,我們可以直接返回一個數據對象,這個數據對象的類型需要和 execute 方法的泛型類型參數 T 一致。例如:

  String result = transactionTemplate.execute(new TransactionCallback<String>() {
      public String doInTransaction(TransactionStatus status) {
          try {
              [...]

              String someResult = someService.doSomething();

              [...]

              return someResult;
          } catch (Exception e) {
              status.setRollbackOnly();
              throw e;
          }
      }
  });

在這個示例中,我們通過返回一個 String 類型的結果來演示如何拿到執行結果。

四、transactionTemplate 隔離級別

在多線程環境下,當多個事務並發執行的時候,可能會出現數據不一致的問題。這時候,事務的隔離級別就非常重要了,它定義了事務之間的可見性和並發性。Spring 的 TransactionTemplate 為我們提供了五種隔離級別,我們可以根據實際業務場景來選擇合適的隔離級別。

五種隔離級別分別為:

  1. ISOLATION_DEFAULT:使用底層資料庫的默認隔離級別,通常為 ISOLATION_READ_COMMITTED
  2. ISOLATION_READ_UNCOMMITTED:讀取未提交數據。
  3. ISOLATION_READ_COMMITTED:只能讀取已提交數據。
  4. ISOLATION_REPEATABLE_READ:可重複讀,事務執行期間,不能修改已讀取的數據。
  5. ISOLATION_SERIALIZABLE:串列化,所有事務按照順序依次執行。

我們可以在 TransactionTemplate 中使用 setIsolationLevel 方法來指定隔離級別,例如:

  TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
  transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
  transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
  transactionTemplate.setTimeout(30);

在這個示例中,我們將事務的隔離級別設置為 ISOLATION_READ_UNCOMMITTED,意味著可以讀取未提交的數據。同時,我們還定義了事務的傳播行為為 PROPAGATION_REQUIRED,超時時間為 30 秒。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/237099.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:03
下一篇 2024-12-12 12:03

相關推薦

  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變數讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分散式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25
  • C語言貪吃蛇詳解

    一、數據結構和演算法 C語言貪吃蛇主要運用了以下數據結構和演算法: 1. 鏈表 typedef struct body { int x; int y; struct body *nex…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web伺服器。nginx是一個高性能的反向代理web伺服器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25

發表回復

登錄後才能評論