EJB事務


事務是一個單元的工作專案遵循ACID特性。ACID代表原子性,一致性,獨立性和永續性。

  • 原子 -如果有任何的工作項失敗,完整的單元被認為是失敗。成功意味著所有專案的成功執行。

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

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

  • 永續性 - 事務應該生存系統故障,如果已經執行或提交。

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

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

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

容器管理的事務

指定EJB3.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
   }
}

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(期間發生的異常)呼叫和使用者物件不會建立那麼UserDetail物件也不會被建立。

Bean管理的事務

Bean管理的事務,事務處理應用水平的異常,可以管理。以下是要考慮的關鍵點

  • Start - 當啟動一個事務中的業務方法。

  • Sucess - 確定成功的情況下,當一個事務被提交。

  • Failed - 確定失敗的情況下,事務回滾。

範例

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()方法呼叫。