EJB事務的特點:
提供聲明式事務與編程式事務
聲明式事務:應用程序只需要關心業務邏輯,由容器來負責事務的管理。這是實踐中常用的方法。
編程時事務:應用程序編碼人員自己寫事務代碼。
② EJB事務編程的類型
A、CMT 容器管理事務
B、BMT Bean管理事務
C、Client-MT Client-Controlled Transaction客戶端管理事務
實體Bean只能用CMT。
CMT:
由容器實現的遠程對象/攔截器,負責調用中間件服務。
優點:在應用程序代碼中,不用編寫事務服務代碼;
缺點:粗粒度,只能在方法級別控制事務。
EJB Bean類中編程方式來使用事務(BMT):
優點:細粒度地控制事務
缺點:事務代理與業務代碼糾纏
Client-controlled Transaction:
優點:客戶端可以精確控制事務
缺點:可能會因爲網絡問題引起是事務的回滾。
3、EJB事務邊界的劃分
事務邊界:事務邊界是指事務從哪裏開始。
CMT的事務特性:
Required:Bean類的方法必須要在事務環境下運行,這是容器默認的事務機制。
事務特性只能使用在CMT。
RequiredNew:Bean類中的方法必須在一個新的事務環境下運行。
Supports:Bean類的方法不需要支持事務。如果客戶端有事務,則繼續沿用原事務環境。
Mandatory:Bean類中方法必須要在事務環境下運行。客戶端不啓動事務則報錯。
NoSupported:Bean類中方法不支持事務。如果客戶端啓動了事務,則掛起該事務。
Never:Bean類中的方法不支持事務。如果客戶端啓動了事務,則報錯。
如果沒有指定參數,@TransactionAttribute 註釋使用REQUIRED 作爲默認參數。
三、EJB事務的編程
1、CMT
@TransationManagement 用在類前,標註該EJB事務管理方式爲Bean | Container(默認)
@TrasactionAttribute 用在方法前,標註事務特性(事務的邊界)
@SessionContext.setRollbackOnly() 回滾標識,setRollbackOnly()方法必須在事務環境下運行。
EJB容器對於非受查異常(主要指RuntimeException)會回滾,事務對於受查異常則會提交事務。
2、BMT
UserTransaction:
① interface
② 提供控制事務的方法
③ 由容器實現,可以使用@Resource注入
UserTransaction.begin()| commit()| .rollback()
3、客戶端控制事務
調用EJB的方法,要求EJB必須採用CMT形式。
4、事務的隔離性
事務的隔離級別:
A、Read uncommitted:性能最高
B、Read committed:解決髒讀問題
C、Repeatable read:解決重複讀取問題
D、Serializable:解決幻讀問題
EJB本身不提供隔離級別的設置,可以通過直接設置數據庫(連接池)的隔離級別。
由於CMT依靠容器開始、提交和回滾事務,所以會限制事務的邊界位置。而BMT則允許通過編程的方式來指定事務的開始、提交和回滾的位置。主要使用的是javax.transaction.UserTransaction接口。
例如:
如果使用有狀態的Session Bean且需要跨越方法調用維護事務,那麼BMT是你唯一的選擇,當然BMT這種技術複雜,容易出錯,且不能連接已有的事務,當調用BMT方法時,總會暫停已有事務,極大的限制了組件的重用。故優先考慮CMT事務管理。
- @Stateless)
- @TransactionManagement(TransactionManagementType.BEAN)
- public class ManagerBean {
- @Resource
- private UserTransaction userTransaction;
- public void placeSnagItOrder(Item item, Customer customer){
- try {
- userTransaction.begin();
- validateCredit(customer);
- ....
- userTransaction.commit();
- } catch (CreditValidationException cve) {
- userTransaction.rollback();
- } catch (CreditProcessingException cpe){
- userTransaction.rollback();
- }
- .....
- }
- }
@TransactionManagement(TransactionManagementType.BEAN) 指定了事務的類型爲BMT,上面沒有用到@TransactionAttribute,因爲它只適用於CMT,在上面代碼中,可以顯示的指定事務的開始與提交,因此更加的靈活。上面最關鍵的地方是注入了UserTransaction資源。其中獲得UserTransaction資源的方式有三種,除了用EJB資源的方式注入以外,還有以下兩種方式:
(1) JNDI查找
- Context context = new InitialContext();
- UserTransaction userTransaction = (UserTransaction) context.lookup(“java:comp/UserTransaction”);
- userTransaction.begin();
- userTransaction.commit();
如果在EJB之外,則可使用此方法,如在不支持依賴注入的JBoss4.2.2的Web工程或helper class即幫助器類中都可以。
(2)EJBContext
- @Resource
- private SessionContext context;
- ...
- UserTransaction userTransaction = context.getUserTransaction(); userTransaction.begin();
- userTransaction.commit();
getUserTransaction方法只能在BMT中使用。如果在CMT中使用,則會拋出IllegalStateException異常。且在BMT中不能使用EJBContext的getRollbackOnly和setRollbackOnly方法,如果這樣使用,也會拋出IllegalStateException異常。
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void insertProduct(String name, Float price, boolean error) {
}
其中,@TransactionAttribute(TransactionAttributeType.REQUIRED)表示指定事務的類型。
如果省略,默認爲CMT方式。
@TransactionAttribute(TransactionAttributeType.REQUIRED)通知容器如何管理事務,
事務的屬性控制了事務的使用範圍,因爲事務之間的關係非常的複雜,這個屬性主要是用來處理事務與事務之間怎樣來處理的的問題。
- 如果產生一個系統異常,容器將自動回滾該事務。 EJBException是RuntimeException的子類,即也是一個系統運行時異常。
如果Bean拋出一個普通的非繼承自RutimeException應用異常,事務將不會自動回滾,但可以
通過調用EJBContext的SetRollbackOnly回滾。 EJB上下文還有一個getRollbackOnly方法,通過返回一個boolean值來確定CMT事務是否已被標記爲回滾。如果開始非常耗資源的操作前判斷此bean的事務已被標記爲回滾,則可以節約很多系統資源。
對於上面的異常回滾操作,還有一更加優雅的方式:
@ApplicationException(rollback=true) - public class CreditValidationException extends Exception {
- @ApplicationException(rollback=true)
- public class CreditProcessingException extends Exception {
- //系統異常
- @ApplicationException(rollback=false)
- public class DatabaseException extends RuntimeException { @ApplicationExcepti把JAVA覈對與不覈對的異常標識爲應用程序異常。其rollback默認爲false,表示程序不會導致CMT自動回滾。