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()方法調用。