Hibernate 处理事务
1. Hibernate 的持久化类
1.1 什么是持久化类
- 持久化类: 就是一个 Java 类(JavaBean),这个 Java类与表建立了映射关系就可以是持久化类;
- 持久化类 = JavaBean + xxx.hbm.xml;
1.2 持久化类的编写规则
- 提供一个无参数的构造方法,因为底层需要进行反射;
- 提供一个唯一的标识 OID, 即映射数据表主键;
数据库中通过主键, Java 对象通过地址确定对象. 持久化类通过唯一标识 OID 确定记录. - 所有属性提供公有的 set 或者 get 方法;
- 标识属性应尽量使用基本数据类型的包装类;
1.3 自然主键和代理主键
- 自然主键: 对象本身的一个属性. 例如,创建一个人员表,使用身份证号(唯一的)作为表的主键.
- 代理主键: 不是对象本身的一个属性. 例如,创建一个人员表,为每个人员单独创建一个作为主键的字段.
- 创建表时,尽量使用代理主键.
1.4 主键生成的策略
<id name="cust_id" column="cust_id">
// 主键的生成策略
<generator class="native"/>
</id>
increment: 适用于 short, int, long 作为主键,不是使用的数据库自动增长机制;- Hibernate 中提供的一种增长机制;
- 先进行查询:
select max(id) from user, 再进行插入,将查询出的最大值+1 作为新记录的主键; - 缺点:不能在集群环境下或者有并发访问的情况下使用;
identity: 适用于 short, int, long 作为主键,但是这个必须使用在自动增长的数据库中.- 底层使用的是数据库的自动增长机制;
sequence: 适用于short, int, long 作为主键.- 底层使用的是序列的增长方式,例如 Oracle 数据库.
uuid: 适用于 char, varchar 类型的作为主键;- 使用随机的字符串作为主键;
native: 使用本地策略,根据底层的数据库不同,自动选择适用于该种数据库的生成策略.- 如果底层使用的 MySql 数据库,相当于
identity; - 如果底层使用的是 Oracle 数据库,相当于
sequence;
- 如果底层使用的 MySql 数据库,相当于
assigned: 主键的生成不用 Hibernate 管理,必须手动设置主键;
2. Hibernate 持久化对象的状态
2.1 Hibernate 持久化类的状态
- Hibernate 为了管理持久化类,将持久化类分成了三个状态:
- 瞬时态(Transient Object), 没有持久化标识 OID,没有被纳入到 Session 对象的管理;
- 持久态(Persistent Object)
- 有持久化标识OID,已经被纳入到 Session 对象的管理;
- 注意: 持久化持久态的对象有自动更新数据库的能力!! 因为 Session 的一级缓存.
- 托管态(Detached Object), 有持久化标识 OID,没有被纳入到 Session 对象的管理;
2.2 Hibernate 持久化对象的状态转换

- 瞬时态
- 获得瞬时态对象:
User user = new User(); - 瞬时态对象转换成持久态:
save() 或 saveOrUpdate(); - 瞬时态对象转换成托管态(不推荐):
user.setId();
- 获得瞬时态对象:
- 持久态
- 获得持久态的对象:
get() 或 load(); - 持久态转换成瞬时态对象:
delete(); - 持久态对象转成托管态对象:
session 的 close() 或 evict() 或 clear()
- 获得持久态的对象:
- 托管态
- 托管态转换成瞬时态:
user.setId(null); - 托管态转换成持久态:
update() 或 saveOrUpdate();
- 托管态转换成瞬时态:
3. Hibernate 的一级缓存
3.1 什么是缓存
- 缓存其实就是一块内存空间,将数据源(数据库或者文件)中的数据存放到缓存中,再次获取的时候,直接从缓存中获取.
可以提升程序的性能.
3.2 Hibernate 框架提供了两种缓存
一级缓存
- 自带的,不可卸载的;
- 一级缓存的生命周期与 session 一致, 一级缓存称为 session 级别的缓存;
二级缓存
- 二级缓存可以在多个 session 中共享数据;
- 二级缓存称为 sessionFactory 级别的缓存;
- 二级缓存是为了增强一级缓存,一级缓存的生命周期比较短暂;
- 二级缓存默认没有开启,需要手动配置才可以使用;
session 对象的缓存概述
- Session 对象中有一系列 java 的集合,这些集合构成了一级缓存;
Session 中与一级缓存相关的方法
session.clear(): 清空一级缓存;session.evict(Object entity): 从一级缓存中清除指定的实体对象;session.flush(): 刷出缓存;
Hibernate 框架是如何做到数据发生变化时,进行同步操作的呢?

4. Hibernate 中的事务和并发
4.1 Hibernate 框架中设置隔离级别
- 需要在 hibernate.cfg.xml 的配置文件中通过标签来配置;
<property name="hibernate.connection.isolation">4</property>- "1"表示
Read uncommitted isolation - "2"表示
Read committed isolation - "4"表示
Repeatable read isolation - "8"表示
Serializable isolation
4.2 丢失更新的问题
如果不考虑隔离性,也会产生写入数据的问题,即丢失更新的问题;
例如: A 和 B 两个事务同时对某一条记录做修改,就会引发丢失更新的问题;
解决方案
- "悲观锁"
- 采用的是数据库提供的一种锁机制,如果采用了这种机制,在SQL语句的后面添加
for update子句 - 当 A 事务在操作该条记录时,会把该条记录锁起来,其他事务是不能操作这条记录的;
- 只有当 A 事务提交后,锁释放了,其他事务才能操作该条记录;
- 采用的是数据库提供的一种锁机制,如果采用了这种机制,在SQL语句的后面添加
- "乐观锁"
- 采用版本号的机制来解决,会在表结构添加一个字段
version=0,默认值为 0; - 当 A 事务在操作完该条记录,提交事务时,会先检查版本号,只有版本号值相同,才可以提交事务.
同时,更新版本号version=1; - 当 B 事务在操作完该条记录,提交事务时,会先检查版本号,如果发现版本号不同,程序会抛出异常.
- 采用版本号的机制来解决,会在表结构添加一个字段
- "悲观锁"
Hibernate 框架解决丢失更新的问题
- "悲观锁":较少使用,效率慢
- "乐观锁"
- 在对应的 JavaBean 中添加一个属性,名称可以是任意的.并提供 get 和 set 方法.
例如:private Integer version; - 在映射的配置文件中,提供
<version name="version"/>标签即可;
- 在对应的 JavaBean 中添加一个属性,名称可以是任意的.并提供 get 和 set 方法.
4.3 绑定本地 Session
- JavaWeb 中的事务,需要在业务层使用 Connection 来开启事务
- 一种是通过参数的方式传递;
- 另一种是把 Connection 绑定到 ThreadLocal 对象中;
- Hibernate 框架,使用 session 对象开启事务.框架提供了 ThreadLocal 的方式,传递 session 对象

// 需要在 hibernate.cfg.xml 的配置文件中提供如下配置
<property name="hibernate.current_session_context_class">thread</property>
// 重写 HiberanteUtils 工具类
public class HibernateUtils {
private static final Configuration CONFIG;
private static final SessionFactory FACTORY;
static{
CONFIG = new Configuration().configure();
FACTORY = CONFIG.buildSessionFactory();
}
public static Session getCurrentSession(){
// 从 ThreadLocal 中获取当前 session 对象
// 该对象不用再手动关闭,线程结束了,会自动关闭.
return FACTORY.getCurrentSession();
}
}
参考资料
Hibernate 处理事务的更多相关文章
- Hibernate中事务的隔离级别设置
Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下
- (转载)Hibernate的事务管理
Hibernate的事务管理 事务(Transaction)是工作中的基本逻辑单位,可以用于确保数据库能够被正确修改,避免数据只修改了一部分而导致数据不完整,或者在修改时受到用户干扰.作为一名软件设计 ...
- atitit.spring hibernate的事务机制 spring不能保存对象的解决
atitit.spring hibernate的事务机制 spring不能保存对象的解决 sessionFactory.openSession() 不能..log黑头马sql语言.. sessionF ...
- Hibernate学习笔记(三)—— Hibernate的事务控制
Hibernate是对JDBC的轻量级封装,其主要功能是操作数据库.在操作数据库过程中,经常会遇到事务处理的问题,接下来就来介绍Hibernate中的事务管理. 在学习Hibernate中的事务处理之 ...
- Hibernate的事务管理
Hibernate的事务管理 事务(Transaction)是工作中的基本逻辑单位,可以用于确保数据库能够被正确修改,避免数据只修改了一部分而导致数据不完整,或者在修改时受到用户干扰.作为一名软件设计 ...
- JavaWeb_(Hibernate框架)Hibernate中事务
Hibernate中事务 事务的性质 事物的隔离级别 配置事务的隔离级别 事务的性质 原子性:原子,不可再分,一个操作不能分为更小的操作,要么全都执行,要么全不执行. 一致性:事务在完成时,必须使得所 ...
- 七、hibernate的事务使用
hibernate中事务隔离级别 1:读未提交 2:读已提交 4:可重复读 8:可串行化 hibernate事务使用 在核心配置文件中配置事务隔离级别 <property name=" ...
- 事务种类jdbc,Hibernate,JTA事务
JDBC事务 String URL="jdbc:sqlserver://localhost:1433;databaseName=test2"; String USER=" ...
- Hibernate中事务声明
Hibernate中JDBC事务声明,在Hibernate配置文件中加入如下代码,不做声明Hibernate默认就是JDBC事务. 一个JDBC 不能跨越多个数据库. Hibernate中JTA事务声 ...
- 【Java EE 学习 53】【Spring学习第五天】【Spring整合Hibernate】【Spring整合Hibernate、Struts2】【问题:整合hibernate之后事务不能回滚】
一.Spring整合Hibernate 1.如果一个DAO 类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了:如果一个DAO类没有 ...
随机推荐
- HR问“预期薪资是多少”,这么说能加薪zz
每年过完节,收好上一年的年终奖,身边人就开始蠢蠢欲动,招聘市场也异常火爆,节前各种裁员的新闻,过了个节都变成了“我们还要继续招人”. 年景不好,人才更是成了紧俏货.可现实中,我却发现,优质的人才未必能 ...
- java 发送带Basic Auth认证的http post请求实例代码
构造http header private static final String URL = "url"; private static final String APP_KEY ...
- python模块学习之warnings
warnings.warn(message, category=None, stacklevel=, source=None) 发出警告,或者忽略它或引发异常. category参数(如果给定)必须是 ...
- nyoj 740 “炫舞家“ST
“炫舞家“ST 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 ST是一个酷爱炫舞的玩家.TA很喜欢玩QQ炫舞,因此TA也爱屋及乌的喜欢玩跳舞机(Dance Dance ...
- 说说Java中的资源文件的读取
最近在看spring的资源获取时发现JDK里存在几种不同方式的资源获取,因比较混乱特地总结起来帮助和我一样混乱的人理解.下面是我项目的类结构图,在 src/main/java 下有两个类 Resour ...
- Android App常规测试内容
转自:https://mp.weixin.qq.com/s?__biz=MzU0NjcyNDg3Mw==&mid=2247484053&idx=1&sn=116fe8c7eed ...
- spring mvc中拦截器配置mvc:interceptors
其实在mvc:interceptors标签中,有两种类型的配置,一种直接配置一个bean(bean和ref归为一类),另一种还要配置上拦截的路径和排除的路径.直接配置的bean那就代表对所有的请求进行 ...
- Retrofit--官网2.1.0
Retrofit--官网2.1.0 android Retrofit 介绍 API 描述 请求方法 URL 处理 请求体 表单的 ENCODED 和 MULTIPART HEADER 处理 同步 VS ...
- Python 中 global、nonlocal的使用
1.在学习python过程中很重要的一点需要记住:如果在函数内部定义了跟全局变量同名的变量,那么该变量将是局部变量,而全局变量的引用在该函数范围内将失效. x = 9 def a(): x = 10 ...
- 第二百零六节,jQuery EasyUI,Menu(菜单)组件
jQuery EasyUI,Menu(菜单)组件 学习要点: 1.加载方式 2.菜单项属性 3.菜单属性 4.菜单事件 5.菜单方法 本节课重点了解 EasyUI 中 Menu(菜单)组件的使用方法, ...