hibernate事务操作

一、事务相关概念
1. 什么是事务
数据库事务是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。
2. 事务特性
一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。
原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。
一致性:事务在完成时,必须使所有的数据都保持一致状态。
隔离性:由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。
持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
3. 不考虑隔离性产生问题
(1)脏读
(2)不可重复读
(3)虚读
4. 设置事务隔离级别
    mysql默认隔离级别 repeatable read
5. Hibernate 也可以在核心配置文件中配置事务隔离级别
<!--
事务隔离级别:
hibernate.connection.isolation = 4
 
1 - Read uncommitted isolation(未提交读:脏读、不可重复读、幻读均可能发生)
2 - Read committed isolation(已提交读:防止脏读发生,不可重复读、幻读均可能发生)
4 - Repeatable read isolation(可重复读:防止脏读、不可重复读发生,幻读可能发生)
8 - Serializable isolation(可串行化:防止脏读、不可重复读、幻读发生)
-->
<propertyname="hibernate.connection.isolation">4</property>
二、hibernate事务规范写法
1. 代码结构
try{
   开启事务
   提交事务
}catch(){
   回滚事务
}finally{
   关闭

}

2. 代码示范

@Test
	public void testTs() {
		Session session = null;
		Transaction ts = null;
		try {
			session = HibernateUtils.getSessionFactory().openSession();
			ts = session.beginTransaction();
			User user = new User();
			user.setUserName("小明");
			user.setPassword("8888");
			user.setAddress("中国");
			session.save(user);
			int i = 10/0;
			//提交事务
			ts.commit();
		}catch(Exception e) {
			e.printStackTrace();
			//回滚事务
			ts.rollback();
		}finally {
			//关闭资源
			session.close();
		}
	}

三、hibernate绑定session

1. 为什么要把Session与本地线程绑定??

openSession():

  • 总是创建一个新的session对象
  • 你需要去明确的关闭session对象
  • 在单线程环境它比getCurrentSession()更慢
  • 你也不需要去配置任何属性,你就能够使用这个方法

getCurrentSession():

  • 如果session不存在,它将创建一个新的session,否则在当前hibernate环境中使用同一个session
  • 不需要去关闭session对象,它将自动被hibernate内部机制关闭
  • 在单线程环境它比opensession更快
  • 你需要去配置中附加hibernate.current_session_context_class这个属性,才能够调用getCurrentSession()方法否则将会抛出异常

所以在这里openSession()和getCurrentSession()的主要区别就是快和慢的区别。开启事务,还是用getCurrentSession()比较好,因为方便且快。

2. 我们怎样获取与本地线程绑定的session

注:Hibernate已经帮我们实现了session与本地线程绑定

(1)首先在hibernate核心配置文件中配置---hibernate.cfg.xml

在第二部分配置
<property name="hibernate.current_session_context_class">thread</property>
//其中,上面的值一共有三个,但是我们一般只用thread,即Session对象与本地线程进行绑定。
- thread:Session对象的生命周期与本地线程绑定
- jta:Session对象的生命周期与JTA事务绑定
- managed:Hibernate委托程序来管理Session对象的生命周期

(2)java代码

  • 在Utils工具类中获取session
public class HibernateUtils {

	private static final Configuration cfg;
	private static final SessionFactory sessionFactory;
	//静态代码块实现
	static {
		cfg = new Configuration().configure();
		sessionFactory =cfg.buildSessionFactory(); 
	}
	
	//提供返回与本地线程帮的session的方法 
	public static Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}
	//使用静态方法返回SessionFactory对象
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}
  • 测试代码
    @Test
    public void testTs() {
    	Session session = null;
    	Transaction ts = null;
    	try {
    		//与本地线程绑定的session
    		session = HibernateUtils.getCurrentSession();
    		ts = session.beginTransaction();
    		User user = new User();
    		user.setUserName("小明");
    		user.setPassword("8888");
    		user.setAddress("中国");
    		session.save(user);
    		ts.commit();
    	}catch(Exception e) {
    		e.printStackTrace();
    		//回滚事务
    		ts.rollback();
    	}finally {
    		//关闭资源
    		//session.close();
    	}
    }
    因为我们这里的session是绑定了本地线程的session,当本地线程被关闭后,session也就自然而然的被关闭了。就像是同一根绳子上面的蚂蚱。这样也就不用我们去关闭session了。

猜你喜欢

转载自blog.csdn.net/SkyFire1121/article/details/79430760