数据库并发操作

enxiuwang 2010-01-26 09:07:30
我的应用是hibernate+c3p0完成数据库操作,服务器是weblogic和oracle

现在正在做压力测试,使用loadrunner,测试结果是:当300人同时并发登陆时,也就是查询数据库时,没有任何错误,但并发向数据库插入数据,3个人就不行了,这是怎么回事?用户正常操作的时候没事,出错时控制台显示session is closed,session was been closed之类的,哪位朋友见过同样的现象,帮帮忙呀!
...全文
223 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
bunrise 2010-01-26
  • 打赏
  • 举报
回复
你把service放在方法里声明看一下
colin_pxx 2010-01-26
  • 打赏
  • 举报
回复
你查询的时候session关掉了吗
enxiuwang 2010-01-26
  • 打赏
  • 举报
回复
非常感谢caizhh,我的getSession()方法是在hibernateutil中的,这个类是eclipse生成的范例,静态会有问题吗?同步是我后加的,现在去了,还是那个样。
还有:我在action中有个属性叫service声名,在execute方法中new了个对象,然后在service的构造方法中调的getSession(),这样会有问题吗?
icy_csdn 2010-01-26
  • 打赏
  • 举报
回复
典型的多线程并发问题。
试试这个
public static synchronized void closeSession(Session session) { }
caizhh 2010-01-26
  • 打赏
  • 举报
回复
楼主可以看看是否静态方法用的多了?

再者,servlet或struts里的action是线程不安全的,在servlet里面不要定义属性变量,我以前做个并发导出就出现过这样的问题,后来把属性变量都放在方法里就OK了

楼主的getSession()方法是用的静态+同步?
怎么不采用实例方法呢?

另外,建议closeSession()方法里session.close();这句代码放在try{}catch{}finally{}
的finally块里面,这样可以保证发生异常后仍然能关闭session
enxiuwang 2010-01-26
  • 打赏
  • 举报
回复
我的每一个请求结束的时候,已经关闭session了!
我插入的时候用的是一个基本的表,没有关联
还有,我是用的struts调用的hibernate,在action中调用service,在service中调用dao,dao调用hibernateUtil.
hibernateUtil的代码如下:
public static synchronized Session getSession()throws HibernateException {

Session session = (Session) threadLocal.get();
try{
if (session == null || !session.isOpen()) {
session = sessionFactory.openSession();
threadLocal.set(session);
}

} catch (HibernateException ex) {
log.error(ex.getMessage());
throw new HibernateException(ex);
}
return session;
}

public static void close() {
try {
sessionFactory.close();
} catch (Exception ex) {
log.error(ex.getMessage());

}
}

public static void closeSession(Session session) {

if(session==null)return;
try {
if(session.isOpen())session.close();
} catch (Exception ex) {
log.error(ex.getMessage());
}
}


我也怀疑是请求的太快导致的多个请求使用了同一个session,其中的一个关了,其它的就完蛋了。但不清楚什么原理?
bunrise 2010-01-26
  • 打赏
  • 举报
回复
hibernate延迟加载的问题吧
插入的时候他们是不是获得的都是同一个session呢?
whereusejava 2010-01-26
  • 打赏
  • 举报
回复
赞同关闭session
czmchen 2010-01-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 kalso4212h2o 的回复:]
哦....是关闭了session.....把你DAO的代码发来LOOK LOOK
[/Quote]
正解
APOLLO_TS 2010-01-26
  • 打赏
  • 举报
回复
c3p0配置的不好。网上找找配置的比较好的copy一番。
kalso4212h2o 2010-01-26
  • 打赏
  • 举报
回复
哦....是关闭了session.....把你DAO的代码发来LOOK LOOK
kalso4212h2o 2010-01-26
  • 打赏
  • 举报
回复
没关闭session.....
crazylaa 2010-01-26
  • 打赏
  • 举报
回复
路过帮顶。session没有做到线程安全,估计就是你new的问题,不要定义为类成员变量,直接定义为方法内部变量,或者做同步。
zl3450341 2010-01-26
  • 打赏
  • 举报
回复
建议closeSession()方法里session.close();这句代码放在try{}catch{}finally{}
的finally块里面,
caizhh 2010-01-26
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 enxiuwang 的回复:]
查询的时候关session了,我是在请求的最后将session关的,
service放在方法外面声名和在里面声名有区别吗?我是在方法里面new 的
[/Quote]

刚才说了servlet是线程不安全的,也就是说多个线程访问同一个servlet时,调用的是同一个servlet对象,如果你的service放在方法外面定义,也就是这个servlet的一个成员了,那么多个线程同时访问时候操作的是同一个service,而放在方法里面做局部变量的话,每个线程访问servlet时都有自己独自的service,互不影响。

在servlet的方法外面定义只可以接受final常量。
enxiuwang 2010-01-26
  • 打赏
  • 举报
回复
查询的时候关session了,我是在请求的最后将session关的,
service放在方法外面声名和在里面声名有区别吗?我是在方法里面new 的

67,515

社区成员

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

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