hibernate框架绑定本地的session(八)

有这么一个业务:保存两个user,在dao层分别写两个方法,在service层调用这两个方法。要保证这两个方法在一个事务里面。

代码如下:

servlet

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		User u1 = new User();
		u1.setName("lilei");
		u1.setAge(17);

		User u2 = new User();
		u2.setName("hanmeimei");
		u2.setAge(16);

		new UserService().save(u1, u2);
	}
service
package com.hib.service;

import com.hib.dao.UserDao;
import com.hib.domain.User;

public class UserService {

	public void save(User u1, User u2) {
		UserDao userDao = new UserDao();
		userDao.save1(u1);
		int a = 10 / 0;
		userDao.save2(u2);
	}
}
dao
package com.hib.dao;

import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hib.domain.User;
import com.hib.utils.HibernateUtils;

public class UserDao {
	public void save1(User u1) {
		Session session = HibernateUtils.getSession();
		Transaction tx = session.beginTransaction();
		session.save(u1);
		tx.commit();
		session.close();
	}

	public void save2(User u2) {
		Session session = HibernateUtils.getSession();
		Transaction tx = session.beginTransaction();
		session.save(u2);
		tx.commit();
		session.close();
	}
}
在service层,如果抛出了异常,第一个user能够保存,第二个user不会被保存。这不符合业务要求。

那么在service层开启事务,代码修改如下:

hibernate.cfg.xml添加一个配置项

<!-- 开启绑定本地session -->
<property name="hibernate.current_session_context_class">thread</property>

HibernateUtils添加方法

	/**
	 * 业务层开事务,就用这个
	 * @return
	 */
	public static Session getCurrentSession() {
		// 从ThreadLocal类中获取到session对象
		return FACTORY.getCurrentSession();
	}

service

package com.hib.service;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hib.dao.UserDao;
import com.hib.domain.User;
import com.hib.utils.HibernateUtils;

public class UserService {

	public void save(User u1, User u2) {
		UserDao userDao = new UserDao();

		// 获取session
		Session session = HibernateUtils.getCurrentSession();
		// 开启事务
		Transaction tx = session.beginTransaction();

		try {
			userDao.save1(u1);
			int a = 10 / 0;
			userDao.save2(u2);

			// 提交事务
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			// 出现问题回滚事务
			tx.rollback();
		} finally {
			// 以前,要手动释放资源。现在,session不用关闭,线程结束了,自动关闭
		}
	}
}
dao
package com.hib.dao;

import org.hibernate.Session;

import com.hib.domain.User;
import com.hib.utils.HibernateUtils;

public class UserDao {
	public void save1(User u1) {
		Session session = HibernateUtils.getCurrentSession();
		session.save(u1);
	}

	public void save2(User u2) {
		Session session = HibernateUtils.getCurrentSession();
		session.save(u2);
	}
}

Hibernate openSession() 和 getCurrentSession的区别

getHiberanteTemplate 、getCurrentSession和OpenSession 
采用getCurrentSession()创建的Session会绑定到当前的线程中去、而采用OpenSession()则不会。

采用getCurrentSession()创建的Session在commit或rollback后会自动关闭,采用OpenSession()必须手动关闭。

采用getCurrentSession()需要在Hibernate.cfg.xml配置文件中加入如下配置:

如果是本地事物,及JDBC一个数据库:

<propety name=”Hibernate.current_session_context_class”>thread</propety>

如果是全局事物,及jta事物、多个数据库资源或事物资源:

<propety name=”Hibernate.current_session_context_class”>jta</propety>

使用spring的getHiberanteTemplate 就不需要考虑事务管理和session关闭的问题:


openSession创建session时autoCloseSessionEnabled参数为false,即在事物结束后不会自动关闭session,需要手动关闭,如果不关闭将导致session关联的数据库连接无法释放,最后资源耗尽而使程序当掉。              

getCurrentSession创建session时autoCloseSessionEnabled,flushBeforeCompletionEnabled都为true,并且session会同sessionFactory组成一个map以sessionFactory为主键绑定到当前线程。

getCurrentSession():从上下文(配置文件current_session_context_class: thread 使用Connection自动管理;jta(java transaction api) 由Application Server提供的分布式事务管理,Tomcat本身不具备此能力,JBoss、WebLogic具备)找,如果有,则用旧的,否则创建新的,事务提交自动Close;

getCurrentSession本地事务(本地事务:jdbc)时 要在配置文件里进行如下设置:

如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>

 

总之:

 getCurrentSession () 使用当前的session
 openSession()         重新建立一个新的session

 在一个应用程序中,如果DAO 层使用Spring 的hibernate 模板,通过Spring 来控制session 的生命周期,则首选getCurrentSession ()。


源码下载

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值