hibernate_事务处理、session管理

 所谓的事务就是指逻辑上的一组操作,这个操作要么全都成功,要么全都失败。

1. 事务的特性

事务特性说明
原子性事务的逻辑操作是一个单位,不可被分割。
一致性事务的执行前后,数据完整性要保持一致。
隔离性一个事务在执行的过程中不受到其他事务的干扰。
持久性一旦事务结束,数据就永久保存数据库。

 
2.并发操作引发的读问题

  • 脏读
     所谓的脏读就是指一个事务读到另一个事务未提交的数据。
  • 不可重复读
     所谓的不可重复读就是指一个事务读到另一个已经提交数据(update),导致查询结果不一样。
  • 虚读
     所谓的虚读就是一个事务读到另一个事务已经提交的数据(insert),导致查询结果不一样。
    解决方法:设置事务的隔离级别,然后在hibernate中设置事务的隔离级别。
//在核心配置文件中设置,X的取值为 1、2、4、8(对应隔离级别)
<property name="hibernate.connection.isolation">
    X
</property>
隔离级别隔离级别名称作用
1Read uncommitted isolation(未提交读)以上问题都不能解决
2Read committed isolation(已提交读)只能避免脏读
4Repeatable read isolation(重复读)能够避免脏读和不可重复读
8Serializable isolation(串行)能够解决以上三种问题

 
3. 并发操作引发的写问题
 并发操作的时候,很经常会引发丢失更新。为了避免这一情况,解决的方法有乐观锁和悲观锁两种机制。

  • 悲观锁(排它锁)
     悲观锁又称之为排它锁,这是数据库自带的一种锁机制,它解决丢失更新的方法是在操作的时候获取锁,在操作完成后释放锁,在操作过程中,别的事务无法获取到锁。简而言之就是:A事务在进行更新操作的时候,B事务无法进行更新操作。
//在获取Session后,在事务上设置悲观锁
Customer customer = (Customer) session.get(Customer.class, 3, LockMode.UPGRADE);
  • 乐观锁
    所谓的乐观锁是在数据库增加某一个字段(Integer类型),以这个字段作为标识,在进行更新的时候进行对比字段是否相同,如果不相同,更新就失败了。如果相同,则提交事务,并且在字段+1
//找到映射文件,在映射文件中将这个字段进行设置,比如Customer中的ver字段作为标识,那么在Customer中进行一下配置
//在class标签下,进行设置version标签
<version name="ver" />

4. session管理
我们在操作事务的时候,经常会遇见两个小事务组成的一个个事务。如果这两个小事务使用的session不是同一个的话,会导致回滚的时候,只有一个小事务回滚。这就要求我们用的session必须是同一个。

//在核心配置文件中设置,在标签hibernate-configuration下的标签session-factory下的子标签property中进行如下设置

<!-- 使用当前线程中的session -->
<property name="hibernate.current_session_context_class">
    thread
</property>
//如果没有在核心文件中配置session管理,那么以下两个session是不相同的:
Session session1 = sessionFactory.openSession();
Session session2 = sessionFactory.openSession();

//结果为false,两个session不是同一个
session1 == session2


//如果在核心配置文件中设置了session管理,那么以下两个session就是相同的。
Session session1 = sessionFactory.getCurrentSession();
Session session2 = sessionFactory.getCurrentSession();

//结果为true,两个session是同一个
session1 == session2

5. 本地线程session过程详解
<1>绑定线程
当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回。

<2>返回线程session
当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象

<3>session提交事务
当 threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动清理 sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. 当 threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象

 <<4>提交后再使用线程session的情况
若 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会又创建一个新的 Session(sessionB) 对象, 把该对象与 threadB绑定, 并将 sessionB 返回

 特别注意:当前线程中的session不需要进行关闭,线程结束后自动关闭!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值