SessionBean从功能上可以分为两类:
第一类:成为EAO:用于封装底层的实体和JPA,本质上其功能就是DAO。(不需要事务控制。因为JPA本质是对ORM实现的封装。)
第二类:充当业务组件:是底层EAO对象的Facade,系统控制器(如struts中的Action,springMVC中的Controller)将调用他们的业务方法来处理用户请求。(需要添加事务控制。因为它代表了一次完整的业务逻辑)
EJB的事务管理机制仍然是建立在JTA事务基础之上,因此应用服务器会负责处理事务管理的底层细节。
EJB3中仍提供容器管理事务(CMT)和Bean管理事务(BMT)两种,并允许采用Annotation机制来指定事务属性,替代了EJB2中的XML配置文件方式。
对于CMT:容器负责决定事务的边界:方法开始就是事务开始,方法结束就是事务结束。
对于BMT:事务边界由开发人员灵活决定(事务开始、事务回滚、事务结束)
一.容器管理事务
CMT:容器负责决定事务的边界:方法开始就是事务开始,方法结束就是事务结束。
(1)Annotation控制事务方式
SessionBean的事务管理机制与MDB的事务管理方式完全一样,都是通过在Bean上使用@TransactionManagement、 @TransactionAttribute两个Annotation来控制的。无需对该接口代码进行任何改变。
1) @TransactionManagement,value属性设置事务处理方式:CMT?还是BMT?,如:
TransactionManagementType.BEAN:指定使用BMT管理事务
TransactionManagementType.CONTAINER:指定使用CMT管理事务
2)@TransactionAttribute,既可以用于修饰SessionBean或MDB 的Bean实现类,也用于修饰某个业务方法(优先),
并通过value值,设置事务属性为枚举类型之一:
(2)捕获‘自定义异常’
默认,发生系统异常,CMT会控制事务回滚;若为自定义异常,不会回滚。
但可以,手工控制‘自定义异常’回滚,方式如下:
第一种:使用EJBContext的setRollbackOnly(),显示控制代码回滚
第二种:使用@ApplicationException Annotation,指定rollback属性为true即可
(3)注意
CMT意味着容器管理EJB业务方法中的事务,因此开发者不应该在开发时,调用任何开始、结束事务的方法
二.Bean管理
对于BMT:事务边界由开发人员灵活决定(事务开始、事务回滚、事务结束),主要通过UserTransaction来控制事务。本质,就是通过编程操作JTA事务管理器。
(1)EJB的Bean类中获取UserTransaction对象的,3种方式:
第一种:使用@Resource Annotation执行依赖注入
第二种:通过JNDI查找获取,如:UserTransaction ut=(UserTransaction)ctx.lookup("UserTransaction");
第三种:使用EJBContext的getUserTransaction()方法获取,如:UserTransaction ut=ctx.getUserTransaction();
(2)UserTransaction 中所含方法简单解析 (略)
三.对比CMT和BMT
(1)特点
CMT(默认):容器负责决定事务的边界:方法开始就是事务开始,方法结束就是事务结束。
BMT:事务边界由开发人员灵活决定(事务开始、事务回滚、事务结束) 。本质,通过编程操作JTA事务管理器。
通常,EJB容器建议使用CMT事务管理。
(2)优缺点
BMT优点:更灵活!开发者自行决定事务边界
BMT缺点:
1.由于开发者采用硬编码方式来实现事务管理,不可避免的导致业务逻辑和是无逻辑混淆的缺陷,切难于切换其它管理方式。
2. 客户端调用BMT方法时,会暂停当前已有事务,就制约了组件的复用
(3)BMT有两种必须存在的场景,以及对应的争议:
1)开发者需要为业务方法中某段代码添加事务。(为何不将这段代码抽离?封装成一个方法?)
2)有状态SessionBean需要跨方法调用维护事务,也就是需要将多个方法放在一个事务中进行维护。(显示多个方法组成了一个完整的业务逻辑,为何不将它们整体封装成一个业务方法)
四.总结
SessionBean中事务管理,分为两种:容器管理事务(CMT)和Bean管理事务(BMT)
CMT(默认):容器负责决定事务的边界:方法开始就是事务开始,方法结束就是事务结束。BMT:事务边界由开发人员灵活决定(事务开始、事务回滚、事务结束) 。本质,通过编程操作JTA事务管理器。