我的项目有一个扣费的业务需要用一个完整的事务封装,而我考虑让数据库连接数尽可能的少,所以用了一个session,并且执行具体操作的时候把这个session传递给数据库操作函数(数据库操作函数封装在另一个类中,util对象是这个类的实例):
Session mysession=HibernateUtil.currentSession();
Transaction tx = null;
try {
tx=mysession.beginTransaction();
System.out.println("Transaction begin!");
//用户身份验证,用户的对象信息存储在subscriber对象中
Subscriber subscriber=util.getSubscriberByAuthcode_new(mysession, authcode);
//用户要购买的节目信息存储在program对象中
ProgramPrice program = util.getProgramByGUID_new(mysession,GUID);
//给该用户的账户扣除该节目的费用
util.deductBalance_new(mysession,subscriber, program);
String result = "0" + "#" + program.getPrice();
//提交这个事务
tx.commit();
System.out.println("Transaction has commited!");
return result;
} catch (Exception e) {
log.error("catch Exception: " + e.getMessage());
if(tx!=null)
tx.rollback();
}finally{
HibernateUtil.closeSession();
}
这样做的话,第一次提交应用正常运行。但是第二次再刷新网页,提示:session is closed! 难道说不可以这样只申请一个session然后传给各个数据库操作函数以保证一个事务就使用一个session? 如果我又想使用这种包含多个数据库操作的事务,又想尽量减少数据库连接数,到底该怎么做?谢谢!
Session mysession=HibernateUtil.currentSession();
Transaction tx = null;
try {
tx=mysession.beginTransaction();
System.out.println("Transaction begin!");
//用户身份验证,用户的对象信息存储在subscriber对象中
Subscriber subscriber=util.getSubscriberByAuthcode_new(mysession, authcode);
//用户要购买的节目信息存储在program对象中
ProgramPrice program = util.getProgramByGUID_new(mysession,GUID);
//给该用户的账户扣除该节目的费用
util.deductBalance_new(mysession,subscriber, program);
String result = "0" + "#" + program.getPrice();
//提交这个事务
tx.commit();
System.out.println("Transaction has commited!");
return result;
} catch (Exception e) {
log.error("catch Exception: " + e.getMessage());
if(tx!=null)
tx.rollback();
}finally{
HibernateUtil.closeSession();
}
这样做的话,第一次提交应用正常运行。但是第二次再刷新网页,提示:session is closed! 难道说不可以这样只申请一个session然后传给各个数据库操作函数以保证一个事务就使用一个session? 如果我又想使用这种包含多个数据库操作的事务,又想尽量减少数据库连接数,到底该怎么做?谢谢!
解决方案 »
- 如何解决拥塞问题
- 加载项目的时候一直抱着个错误 究竟是怎么回事啊
- tomcat 的问题
- Weblogic 8.1 如何记录用户度应用程序的操作日志
- [急]如何用JAVA写出一个站内搜索
- HttpUrlConnection - locked <0x2871d648> (a java.io.BufferedInputStream)
- 读取XML文件,并将数据导人到数据库---用哪种技术好?
- 请教关于EJB在远程机上发布的问题.谢谢
- POI如何根据:数据库中存的图片路径,需要拼接服务器地址才能显示出来图片,如何图片导入word文档中?
- springMVC拦截器配置一个不拦截的url,使用localhost:8080就可以直接访问,换成127.0.0.1:8080就会被拦截,这是怎么回事啊
- 请问CORBA用DSI方式编写服务器如何设置数组和结构类型的参数和返回值
- java连接数据库提示出错找不到localhost
public class HibernateFilter implements Filter {
private static ThreadLocal<Session> hibernateHolder = new ThreadLocal();
private static SessionFactory factory = null;
public void destroy() {
} public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
try {
filterChain.doFilter(servletRequest, servletResponse);
} finally {
Session session = (Session)hibernateHolder.get();
if (session != null) {
if (session.isOpen()) {
session.close();
}
hibernateHolder.remove();
}
}
} public void init(FilterConfig filterConfig) throws ServletException {
try {
Configuration cfg = new Configuration().configure();
factory = cfg.buildSessionFactory();
}catch(Exception e) {
e.printStackTrace();
throw new ServletException(e);
}
}
public static Session getSession() {
Session session = (Session)hibernateHolder.get();
if (session == null) {
session = factory.openSession();
hibernateHolder.set(session);
}
return session;
}
}
在web.xml中添加:filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>xx.xx.xx.util.HibernateFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这句代码有问题了,因为currentSession只有一个,而你这样会关闭session,要不你就用filter来判断session有没有关闭,关闭了就打开另外一个,要不,你可以选择使用对于每个线程有一个session,ThreadLocal <Session> hibernateHolder = new ThreadLocal();
我推荐第二种方案。
这样就避免了延时加载所报的session is cloase()
为什么你不是写在destroy里面而是写在doFilter里面,对于session关闭
Spring
他本身就提供了事务的支持~
LZ可以去试一下o..
即使有多个session,对应的数据库连接数与只有一个session对应的数据库连接数是一样的,也就是,你用一个session操作跟用多个session操作数据库是一样的。
使用Hibernate时,你就不用管数据库连接问题,只管拿过来用就行了!后台都是封装好的!
Transaction tx = null;
try {
tx=mysession.beginTransaction();
System.out.println("Transaction begin!");
//用户身份验证,用户的对象信息存储在subscriber对象中
Subscriber subscriber=util.getSubscriberByAuthcode_new(mysession, authcode);
//用户要购买的节目信息存储在program对象中
ProgramPrice program = util.getProgramByGUID_new(mysession,GUID);
//给该用户的账户扣除该节目的费用
util.deductBalance_new(mysession,subscriber, program);
String result = "0" + "#" + program.getPrice();
//提交这个事务
tx.commit();
System.out.println("Transaction has commited!");
return result;
} catch (Exception e) {
log.error("catch Exception: " + e.getMessage());
if(tx!=null)
tx.rollback();
}finally{
HibernateUtil.closeSession(); -----------------------------------------2
} 你自己先看清楚你关闭的是什么session,你把总的session关闭了,当然没有session再去支持你的事务了啊