EJB - 事務



事務是單個工作單元,遵循ACID屬性。ACID代表原子性、一致性、隔離性和永續性。

  • 原子性 - 如果任何工作單元失敗,則整個單元將被視為失敗。成功意味著所有專案都成功執行。

  • 一致性 - 事務必須保持系統的狀態一致。

  • 隔離性 - 每個事務獨立於任何其他事務執行。

  • 永續性 - 如果事務已執行或提交,則事務應能夠在系統故障中倖存。

EJB容器/伺服器是事務伺服器,處理事務上下文傳播和分散式事務。事務可以由容器管理,也可以由bean程式碼中的自定義程式碼處理。

  • 容器管理的事務 - 在這種型別中,容器管理事務狀態。

  • Bean管理的事務 - 在這種型別中,開發人員管理事務狀態的生命週期。

容器管理的事務

EJB 3.0指定了以下事務屬性,EJB容器實現這些屬性:

  • REQUIRED - 指示業務方法必須在事務中執行,否則將為該方法啟動一個新事務。

  • REQUIRES_NEW - 指示要為業務方法啟動一個新事務。

  • SUPPORTS - 指示業務方法將作為事務的一部分執行。

  • NOT_SUPPORTED - 指示業務方法不應作為事務的一部分執行。

  • MANDATORY - 指示業務方法將作為事務的一部分執行,否則將丟擲異常。

  • NEVER - 指示如果業務方法作為事務的一部分執行,則將丟擲異常。

示例

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserDetailBean implements UserDetailRemote {
	
   private UserDetail;

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public void createUserDetail() {
      //create user details object
   }
}

使用Required註解將createUserDetail()業務方法設定為Required。

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
public class UserSessionBean implements UserRemote {
	
   private User;

   @EJB
   private UserDetailRemote userDetail;

   public void createUser() {
      //create user 
      //...
      //create user details
      userDetail.createUserDetail();
   }
}

createUser()業務方法使用createUserDetail()。如果在createUser()呼叫期間發生異常並且未建立User物件,則也不會建立UserDetail物件。

Bean管理的事務

在Bean管理的事務中,可以透過在應用程式級別處理異常來管理事務。

以下是要考慮的關鍵點:

  • 啟動 - 何時在業務方法中啟動事務。

  • 成功 - 確定事務要提交的成功場景。

  • 失敗 - 確定事務要回滾的失敗場景。

示例

package com.tutorialspoint.txn.bmt;
 
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;
 
@Stateless
@TransactionManagement(value=TransactionManagementType.BEAN)
public class AccountBean implements AccountBeanLocal {
 
   @Resource
   private UserTransaction userTransaction;

   public void transferFund(Account fromAccount, double fund , 
      Account toAccount) throws Exception{

      try{
         userTransaction.begin();

         confirmAccountDetail(fromAccount);
         withdrawAmount(fromAccount,fund);

         confirmAccountDetail(toAccount);
         depositAmount(toAccount,fund);

         userTransaction.commit();
      }catch (InvalidAccountException exception) {
         userTransaction.rollback();
      }catch (InsufficientFundException exception) {
         userTransaction.rollback();
      }catch (PaymentException exception) {
         userTransaction.rollback();
      }
   }

   private void confirmAccountDetail(Account account) 
      throws InvalidAccountException {
   }

   private void withdrawAmount() throws InsufficientFundException {
   }

   private void depositAmount() throws PaymentException{
   }
}

在此示例中,我們使用UserTransaction介面使用userTransaction.begin()方法呼叫來標記事務的開始。我們使用userTransaction.commit()方法標記事務的完成,如果事務期間發生任何異常,則我們使用userTransaction.rollback()方法呼叫回滾整個事務。

廣告
© . All rights reserved.