【JavaEE】经典JAVA EE企业应用实战-读书笔记10

开发有状态的Session Bean

和无状态的Session Bean并无太大的区别,对开发者来讲,只有如下区别:

1)如果使用Annotation来配置EJB的部署,则将@Stateless改为@Stateful即可。

2)如果使用XML部署描述文件来配置EJB的部署描述信息,则将<session-type>元素的值改为Stateful即可。

对于有状态的Session Bean而言,客户端不要每次都用lookup方法去获取Session Bean,因为每次调用都会获取一个新的Session Bean,新的Session Bean将无法维护客户端的会话状态。

正确的用法是将Session Bean放入HTTP Session中,保证多个页面中使用的是同一个Session Bean

 

对大部分EJB服务器来说,都会通过一个EJB池来维护无状态的Session Bean,在该EJB池中持有多个无状态Session Bean的实例,这些实例都处于待命状态,准备被客户端调用。

一个无状态的Session Bean从诞生到消亡大致要经历如下的过程。

1)EJB容器开始创建无状态Session Bean的实例。

2)EJB容器对EJB实例执行依赖注入

3)EJB容器滴啊用EJB内以@PostConstruct修饰的生命周期方法。

4)EJB进入待命状态

5)EJB容器调用EJB内以@PreDestroy修饰的生命周期方法

6)EJB实例被垃圾回收

无状态Session Bean3个状态:不存在状态、待命状态和被销毁状态。

 

有状态的Session Bean比无状态的Session Bean多了一个去活状态,多了两个Annotation@PrePassive@PostActivate

@PostConstruct:修饰的方法会在EJB创建之后被EJB容器调用。

@PreDestroy:修饰的方法会在EJB被销毁之前被EJB容器调用。

@PostActivate:修饰的方法将会在有状态的Session Bean从去活状态恢复出来之后被EJB容器调用,该方法执行完成之后该EJB再次进入待命状态。

@PrePassivate:修饰的方法将会在有状态的Session Bean去活之前被EJB容器调用。

@Remove:修饰的方法实际上应该属于一个业务方法,用于被客户端调用,当客户端调用某个有状态Session Bean@Remove修饰的方法之后,相当于客户端通知服务器应该删除该有状态的Session Bean。因此EJB容器会立即调用该Session Bean@PreDestroy修饰的方法,然后销毁该Session Bean

 

在基于EJBJavaEE中,Session Bean从功能上大致分为两类。

1)用于封装底层的实体和JPA,用于访问底层的实体,可称为EAOEntity Access Object)对象,本质上的功能就是DAO

2)充当业务组件,底层EAO对象的Facade(门面),系统控制器(比如StrutsActionJSF的托管Bean等)将调用他们的业务方法来处理用户的请求。

第一类Bean不需要事务控制,第二类的每个业务方法用于处理一次用户请求,代表一次完整的业务逻辑,需要添加事务控制。

CMT的事务边界总是以方法的开始、结束作为边界的。

使用@TransactionManagement时通过其value属性指定使用CMT还是BMT

value属性值只能有如下两个:

TransactionManagementType.BEAN:指定使用BMT

TransactionManagementType.CONTAINER:指定使用CMT

使用<transaction-type>时也只能接收两个值:BeanContainer

 

开发者使用CMT,则应该使用@TransactionAttribut来指定事务属性。

value属性的值可以是javax.ejb.TransactionAttributeType枚举值之一。

@Remote
public interface Cmt {
	void insert();
}
@Stateless(mappedName = "Cmt")
@TransactionManagement(TransactionManagementType.CONTAINER)//重点
@TransactionAttribute(TransactionAttributeType.REQUIRED)//重点
public class CmtBean implements Cmt {
	private DataSource ds = null;
	@Resource
	private SessionContext sessCtx;
	public CmtBean() throws NamingException {
		Context ctx = new InitialContext();
		ds = (DataSource) ctx.lookup("javaee");
	}
	@Override
	public void insert() {
		try {
			Connection conn = ds.getConnection();
			Statement stmt = conn.createStatement();
			int result = stmt.executeUpdate("insert into user values(1,'new','bbb')");
			System.out.println(result);
			// 下面的语句会报错,主键重复
			stmt.execute("insert into user values(1,'new','bbb')");
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
			sessCtx.setRollbackOnly();//重点
		}
	}
}

sessCtx .setRollbackOnly(); 这条代码用于设置 EJB的事务回滚,但是如果其Bean方法执行时引发了其他应用自定义异常,CMT的事务控制将不会让事务回滚。

如果希望调用EJB方法时抛出其他异常也会回滚事务,有两种方式

1)使用EJBContextsetRollbackOnly方法。

2)使用@ApplicationException的注解

第二种方法可以指定一个rollback属性,属性为true则表明执行EJB的业务方法中引发该异常将让事务自动回滚。

由于CMT表示容器会接管EJB业务方法中的事务,因此开发者不应该在EJB业务方法中调用这些方法不限于:

1)java.sql.ConnectionsetAutoCommit(false)commitrollback

2)javax.ejb.EJBContextgetUserTransaction

3)javax.transaction.UserTransaction的任何方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值