远程客户如果一直维持引用,有状态的会话bean在怎样的情况下会超时(或被回收)?

AYellow 2003-07-17 11:27:57
因为EJB常常是远程调用,不知道容器怎么回收资源的?

从JNDI获得一个有状态会话bean的引用,如果我一直将它保持在静态变量中,能够一直使用吗?它会不会超时?容器是如何对它进行回收的?还是在垃圾回收的时候被收调的?

无状态会话bean呢?
...全文
83 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
wafer_w 2003-07-21
  • 打赏
  • 举报
回复
我的意思是不管什么错误你都可以去建新引用,反正引用已经损坏(为什么要追究到底是因为超时、网络、还是其他问题),反正他不可用了,所以就可以丢弃重建!
lglg930 2003-07-20
  • 打赏
  • 举报
回复
up
Jiemi 2003-07-20
  • 打赏
  • 举报
回复
我顶
soyol 2003-07-19
  • 打赏
  • 举报
回复
up
javahui 2003-07-18
  • 打赏
  • 举报
回复
跟HTTPSESSION是同一回事吧
rebornman 2003-07-18
  • 打赏
  • 举报
回复
学紧
biggie 2003-07-18
  • 打赏
  • 举报
回复
有状态会话 Bean 只保存短暂的数据
当用户终止与Session beans互操作的时候.会话终止了
所以用户不操作又想长时间保存是不现实的
然后被抛弃
钝化/激活只是容器管理其状态的方法

回收条件:
超时 (无论是激活的或钝化的)
被调用 remove()



AYellow 2003-07-18
  • 打赏
  • 举报
回复
那么用有状态的session bean不是那么可靠了
sun还说什么用来做购物车,如果超时了都不知道怎么回事
AYellow 2003-07-18
  • 打赏
  • 举报
回复
(流浪的风) 你没有理解我的意思
我的意思是:

》只要从cache里面得到的引用无法用
我怎么知道它无法用,我只是在引用上调用方法的时候受到一个远程异常而已,这也可能是因为数据库异常或是短暂的IO异常引起的,也可能是引用超时。按你的说法,引用超时应该新建,不过运行时我的程序怎么知道是引用超时而不是SQL错误并且去新建一个引用呢
wafer_w 2003-07-18
  • 打赏
  • 举报
回复
数据库不可用或者IO异常,程序都是无法运行的(至少该次读取肯定失败),你除了记日志让系统管理员来解决,还能做什么,难道期望程序能将断了的网线接起来?

如果硬件问题解决了,那么下一次请求的时候自然就不会出错了!
bdsc 2003-07-18
  • 打赏
  • 举报
回复
得到home接口Handle存起来(Serialization),用的时候再create()
wafer_w 2003-07-18
  • 打赏
  • 举报
回复
抛出异常就不可用了啊,管他是数据库异常还是短暂的的IO异常


我怎么知道应该去新建一个引用呢
--
看看那段代码
accpsh 2003-07-18
  • 打赏
  • 举报
回复
我有一个自已做的session bean 。。。。在超时十分钟后自动断开。。在客户端保存数据。。需要的发我eamil:accp@citiz.net 交流交流
AYellow 2003-07-18
  • 打赏
  • 举报
回复
》只要从cache里面得到的引用无法用
我怎么知道它无法用,我只受到一个远程异常而已,这也可能是因为数据库异常或是短暂的IO异常引起的
我怎么知道应该去新建一个引用呢
wafer_w 2003-07-18
  • 打赏
  • 举报
回复
远程服务器重启是比较极端的例子,不过你可以不管是什么原因引起的失效,只要从cache里面得到的引用无法用,你就重新创建一个引用,用完放入cache中,如果这个新创建的引用都没法用,就是程序本身的问题而和会话失效无关了
AYellow 2003-07-18
  • 打赏
  • 举报
回复
书上的例子往往比较简单,只关注于它的知识点
然而我们要做出健壮的程序就必须考虑到各种问题

引用肯定是会失效的,比如远程服务器重启了
不知道的是如果服务器没有重启动的化,我一直保留引用是否可以,服务器怎么知道客户端是否还在引用某个对象?

如果引用失效,在引用上调用方法会有RemoteException,但是引起RemoteException的原因很多,我怎么知道是引用失效引起的呢,这时怎么从错误中恢复?
wafer_w 2003-07-18
  • 打赏
  • 举报
回复
package dataaccess;

import java.sql.*;
import javax.sql.DataSource;
import java.util.Hashtable;
import javax.naming.*;
import javax.ejb.*;
import javax.rmi.PortableRemoteObject;
import session.counter.CounterHome;
import session.title.TitleDAOHome;
import session.editor.EditorDAOHome;

/*
* The ServiceLocator pattern is abstracts away the JNDI
* logic necessary for retrieving a JDBC Connection or EJBHome
* interface
*/
public class ServiceLocator{
private static ServiceLocator serviceLocatorRef = null;
private static Hashtable ejbHomeCache = null;
private static Hashtable dataSourceCache = null;

/*Enumerating the different services available from the Service Locator*/
public static final int COUNTER = 0;
public static final int TITLEDAO = 1;
public static final int EDITORDAO = 2;
public static final int SUBSCRIPTIONDB = 3;

/*The JNDI Names used to lookup a service*/
private static final String COUNTER_JNDINAME="counter/Counter";
private static final String TITLEDAO_JNDINAME="title/TitleDAO";
private static final String EDITORDAO_JNDINAME="editor/EditorDAO";
private static final String SUBSCRIPTIONDB_JNDINAME="jdbc/subscriptionDS";

/*References to each of the different EJB Home Interfaces*/
private static final Class COUNTERCLASSREF = CounterHome.class;
private static final Class TITLECLASSREF = TitleDAOHome.class;
private static final Class EDITORCLASSREF = EditorDAOHome.class;

static {
serviceLocatorRef = new ServiceLocator();
}

/*Private Constructor for the ServiceLocator*/
private ServiceLocator(){
ejbHomeCache = new Hashtable();
dataSourceCache = new Hashtable();
}

/*
* The ServiceLocator is implemented as a Singleton. The getInstance()
* method will return the static reference to the ServiceLocator stored
* inside of the ServiceLocator Class.
*/
public static ServiceLocator getInstance(){
return serviceLocatorRef;
}

/*
* The getServiceName will retrieve the JNDI name for a requested
* service. The service is indicated by the ServiceId passed into
* the method.
*/
static private String getServiceName(int pServiceId)
throws ServiceLocatorException{
String serviceName = null;
switch (pServiceId){
case COUNTER: serviceName = COUNTER_JNDINAME;
break;
case TITLEDAO: serviceName = TITLEDAO_JNDINAME;
break;
case EDITORDAO: serviceName = EDITORDAO_JNDINAME;
break;
case SUBSCRIPTIONDB: serviceName = SUBSCRIPTIONDB_JNDINAME;
break;
default: throw new ServiceLocatorException(
"Unable to locate the service requested in " +
"ServiceLocator.getServiceName() method. ");
}
return serviceName;
}

/*
* Returns the EJBHome Class reference for a requested service.
* If the method can not make a match, it will throw a ServiceLocatorException
* .
*/
static private Class getEJBHomeRef(int pServiceId)
throws ServiceLocatorException{
Class homeRef = null;
switch (pServiceId){
case COUNTER: homeRef = COUNTERCLASSREF;
break;
case TITLEDAO: homeRef = TITLECLASSREF;
break;
case EDITORDAO: homeRef = EDITORCLASSREF;
break;
default: throw new ServiceLocatorException(
"Unable to locate the service requested in " +
"ServiceLocator.getEJBHomeRef() method. ");
}
return homeRef;
}

/*
* The getEJBHome method will return an EJBHome interface for a requested
* service. If it can not find the requested EJB, it will throw a
* servicelocator exception.
*
* The getEJBHome interface caches a requested EJBHome so that the first
* time an EJB is requested, a home interface will be retrieved but then
* be placed into a cache.
*
*/
public EJBHome getEJBHome(int pServiceId)
throws ServiceLocatorException{

/*Trying to find the JNDI Name for the requested service*/
String serviceName = getServiceName(pServiceId);
EJBHome ejbHome = null;

try{
/*Checking to see if I can find the EJBHome interface in cache*/
if (ejbHomeCache.containsKey(serviceName)){
ejbHome = (EJBHome) ejbHomeCache.get(serviceName);
return ejbHome;
}
else{
/*
* If I could not find the EJBHome interface in the cache, look it
* up and then cache it.
* */
Context ctx = new InitialContext();
Object jndiRef = ctx.lookup(serviceName);

Object portableObj =
PortableRemoteObject.narrow(jndiRef, getEJBHomeRef(pServiceId));

ejbHome = (EJBHome) portableObj;

ejbHomeCache.put(serviceName, ejbHome);
return ejbHome;
}
}
catch(NamingException e){
throw new ServiceLocatorException("Naming exception error in ServiceLocator.getEJBHome()" ,e);
}
catch(Exception e){
throw new ServiceLocatorException("General exception in ServiceLocator.getEJBHome",e);
}

}

/*
* The getDBConn() method will create a JDBC connection for the
* requested database. It too uses a cachin algorithm to minimize
* the number of JNDI hits that it must perform.
*/
public Connection getDBConn(int pServiceId)
throws ServiceLocatorException{
/*Getting the JNDI Service Name*/
String serviceName = getServiceName(pServiceId);
Connection conn = null;
try{
/*Checking to see if the requested DataSource is in the Cache*/
if (dataSourceCache.containsKey(serviceName)){
DataSource ds = (DataSource) dataSourceCache.get(serviceName);
conn = ((DataSource)ds).getConnection();

return conn;
}
else{
/*
* The DataSource was not in the cache. Retrieve it from JNDI
* and put it in the cache.
*/
Context ctx = new InitialContext();
DataSource newDataSource = (DataSource) ctx.lookup(serviceName);
dataSourceCache.put(serviceName, newDataSource);
conn = newDataSource.getConnection();
return conn;
}
}
catch(SQLException e){
throw new ServiceLocatorException("A SQL error has occurred in " +
"ServiceLocator.getDBConn()", e);
}
catch(NamingException e){
throw new ServiceLocatorException("A JNDI Naming exception has occurred "+
" in ServiceLocator.getDBConn()" , e);
}
catch(Exception e){
throw new ServiceLocatorException("An exception has occurred "+
" in ServiceLocator.getDBConn()" ,e);
}
}
}
wafer_w 2003-07-18
  • 打赏
  • 举报
回复
抱歉刚才有翻了一下《使用J2EE设计模式编程指南》,它好象没有考虑会发生引用损坏的情况,是否不会有损坏这种情况呢?(因为它毕竟只是一个接口),思考中....

我待会儿把代码发上来给你参考
AYellow 2003-07-18
  • 打赏
  • 举报
回复
如何判断缓存中的引用坏了?
wafer_w 2003-07-18
  • 打赏
  • 举报
回复
Service Locator模式可以解决你的问题
在本地为需要的jndi引用做一个cache,需要时从cache 里面取,如果cache中坏了或没有就再创建,用完了放回cache中
加载更多回复(5)

67,549

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧