事务介绍
一、问题:什么是事务?
事务就是逻辑上的一组操作,组成这组操作的各个单元要么全部成功,要么全都失败。
二、问题:事务四个特性?
1.原子性: 不可分割
2.一致性: 事务在执行前后,要保证数据的一致。
3.隔离性: 一个事务在执行的过程中,不应该受到其它事务的干扰。
4.持久性: 事务一旦结束,数据持久化到数据库。
三、问题:不考虑事务的隔离性,会产生什么问题?
1.脏读: 一个事务读取到另一个事务的未提交数据
2.不可重复读: 一个事务读取到另一个事务提交的数据(主要是指update),会导致两次读取的结果不一致。
3.虚读(幻读): 一个事务读取到另一个事务提交的数据(主要是指insert),会导致两次读取结果不一致.
四、问题:对于上述问题如何解决?
我们可以通过设置隔离级别来解决.
1.READ_UNCOMMITED 读取未提交, 它引发所有的隔离问题
2.READ_COMMITTED 读已提交, 阻止脏读,可能发生不可重复读与虚读.
3.REPEATABLE_READ 重复读 阻止脏读,不可重复读 可能发生虚读
4.SERIALIZABLE 串行化 解决所有问题 不允许两个事务,同时操作一个目标数据。(效率低下)
ORACLE 默认的是事务隔离级别 READ_COMMITTED
MYSQL 默认的事务隔离级别 REPEATABLE_READ
Hibernate中设置事务隔离级别:
<property name="hibernate.connection.isolation ">4</property>
它可取的值有 1 2 4 8
1代表的事务隔离级别为READ UNCOMMITTED
2代表的事务隔离级别为READ COMMITTED
4.代表的事务隔离级别为 REPEATABLE READ
8代表的事务隔离级别为 SERIALIZABLE
Hibernate中session管理
Hibernate提供了三种管理session的方式:
1.Session对象的生命周期与本地线程绑定(ThreadLocal)
2.Session对象的生命周期与JTA事务绑定(分布式事务管理)
3.Hibernate委托程序来管理Session的生命周期
关于本地线程绑定Session。
步骤:
1.需要在hibernate.cfg.xml文件配置:
<!-- 本地线程绑定Session配置 -->
<property name="hibernate.current_session_context_class">thread</property>
2.在获取session时不要在使用openSession而是使用getCurrentSession()方法。
(使用getCurrentSession获取的与线程绑定的session对象,在事务关闭时,session对象也会close,简单说,就不需要我们在手动session.close();)
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
test
public void test1() {
//此时每一次获取都是一个新的Session
Session s1 = HibernateUtils.openSession();
Session s2 = HibernateUtils.openSession();
System.out.println(s1 == s2); //false
Session s3 = HibernateUtils.getCurrentSession();
Session s4 = HibernateUtils.getCurrentSession();
System.out.println(s3 == s4); //true
}