文档章节

Hibernate4教程五:事务和并发

乐在克里特
 乐在克里特
发布于 2017/02/24 13:45
字数 2027
阅读 5
收藏 0
Hibernate本身没有事务的实现
Hibernate 直接使用 JDBC 连接和 JTA 资源,不添加任何附加锁定行为。也就是说你在Hibernate里面使用的事务要么是JDBC的事务,要么是JTA的事务。
Hibernate不锁定内存中的对象
你的应用程序会按照你的数据库事务的隔离级别规定的那样运作,真正对事务的实现和支持也依赖于数据库。
 
对于并发处理,Hibernate提供了乐观锁和悲观锁来进行并发处理
Hibernate对自动乐观并发控制提供版本管理,针对行级悲观锁定,Hibernate 也提供了辅助的(较小的)API,它使用了 SELECT FOR UPDATE 的 SQL 语法
Hibernate的Session是和事务联系在一起的
可以通过Session去获取事务的接口,从而进行事务的控制。
 
数据库事务应该尽可能的短
这样能降低数据库中的锁争用。数据库长事务会阻止你的应用程序扩展到高的并发负载。因此,假若在用户思考期间让数据库事务开着,直到整个工作单元完成才关闭这个事务,这绝不是一个好的设计。
这就引出一个问题:一个操作单元,也就是一个事务单元的范围应该是多大?
一个操作一个?一个请求一个?一个应用一个?
 
反模式:session-per-operation
在单个线程中, 不要因为一次简单的数据库调用,就打开和关闭一次 Session!数据库事务也是如此。也就是说应该禁止自动事务提交(auto-commit)。
 
session-per-request
最常用的模式是 每个请求一个会话。 在这种模式下,来自客户端的请求被发送到服务器端,即 Hibernate 持久化层运行的地方,一个新的 Hibernate Session 被打开,并且执行这个操作单元中所有的数据库操作。一旦操作完成(同时对客户端的响应也准备就绪),session 被同步,然后关闭。会话和请求之间的关系是一对一的关系。
Hibernate 内置了对“当前 session(current session)” 的管理,用于简化此模式。你要做的一切就是在服务器端要处理请求的时候,开启事务,在响应发送给客户之前结束事务,通常使用Servelt Filter来完成。
 
非托管环境下
所谓非托管,指的是:应用程序没有托管到J2EE环境中,通常由Hibernate自己来负责管理数据库连接池。应用程序开发人员必须手工设置事务声明,换句话说,就是手工启动,提交,或者回滚数据库事务。
 
使用JTA
又有两种方式,一种是在Hibernate配置里面修改transaction的factory类,从而在程序里面可以直接使用Hibernate的事务API,也就是程序不用变化。
另外一种方式就是直接通过JNDI去查找UserTransaction,然后直接在程序里面使用JTA的接口来控制事务。
应用程序级别的版本检查
简单点说,就是由应用程序自己实现版本检查来确保对话事务的隔离,从数据访问的角度来说是最低效的,不推荐使用。
 
扩展周期的session和自动版本化
Hibernate 使用扩展周期的 Session 的方式,或者脱管对象实例的方式来提供自动版本检查。单个 Session 实例和它所关联的所有持久化对象实例都被用于整个对话,这被称为 session-per- conversation。
Hibernate 在同步的时候进行对象实例的版本检查,如果检测到并发修改则抛出异常。由开发人员来决定是否需要捕获和处理这个异常(通常的抉择是给用户 提供一个合并更改,或者在无脏数据情况下重新进行业务对话的机会)。
在等待用户交互的时候, Session 断开底层的 JDBC 连接。这种方式以数据库访问的角度来说是最高效的方式。应用程序不需要关心版本检查或脱管对象实例的重新关联,在每个数据库事务中,应用程序也不需要载入读取对象实例。
应用程序级别的版本检查
简单点说,就是由应用程序自己实现版本检查来确保对话事务的隔离,从数据访问的角度来说是最低效的,不推荐使用。
 
扩展周期的session和自动版本化
Hibernate 使用扩展周期的 Session 的方式,或者脱管对象实例的方式来提供自动版本检查。单个 Session 实例和它所关联的所有持久化对象实例都被用于整个对话,这被称为 sessionper-conversation。
Hibernate 在同步的时候进行对象实例的版本检查,如果检测到并发修改则抛出异常。由开发人员来决定是否需要捕获和处理这个异常(通常的抉择是给用户 提供一个合并更改,或者在无脏数据情况下重新进行业务对话的机会)。
在等待用户交互的时候, Session 断开底层的 JDBC 连接。这种方式以数据库访问的角度来说是最高效的方式。应用程序不需要关心版本检查或脱管对象实例的重新关联,在每个数据库事务中,应用程序也不需要载入读取对象实例。
通常不需要自己去管理锁定策略
Hibernate 总是使用数据库的锁定机制,从不在内存中锁定对象。因而用户并不需要花很多精力去担心锁定策略的问题。通常情况下,只要为 JDBC 连接指定一下隔离级别,然后让数据库去搞定一切就够了。
然而,高级用户有时候希望进行一个排它的悲观锁定,或者在一个新的事务启动的时候,重新进行锁定。
 
类 LockMode 定义了Hibernate 所需的不同的锁定级别
1:当更新或者插入一行记录的时候,锁定级别自动设置为LockMode.WRITE。
2:当用户显式的使用数据库支持的 SQL 格式 SELECT ... FOR UPDATE 发送 SQL 的时候,锁定级别设置为 LockMode.UPGRADE。
3:当用户显式的使用 Oracle 数据库的 SQL 语句 SELECT ... FOR UPDATE NOWAIT 的时候,锁定级别设置 LockMode.UPGRADE_NOWAIT。
4:当 Hibernate 在“可重复读”或者是“序列化”数据库隔离级别下读取数据的时候,锁定模式自动设置为 LockMode.READ。这种模式也可以通过用户显式指定进行设置。
5:LockMode.NONE 代表无需锁定。在 Transaction 结束时, 所有的对象都切换到该模式上来。与session 相关联的对象通过调用 update() 或者 saveOrUpdate() 脱离该模式。
 
显示的指定锁定模式
1:调用 Session.load() 的时候指定锁定模式(LockMode)。
2:调用 Session.lock()。
3:调用 Query.setLockMode()。
显示指定锁定模式的说明
1:如果在 UPGRADE 或者 UPGRADE_NOWAIT 锁定模式下调用 Session.load(),并且要读取的对象尚未被session 载入过,那么对象通过 SELECT ... FOR UPDATE 这样的 SQL 语句被载入。如果为一个对象调用 load() 方法时,该对象已经在另一个较少限制的锁定模式下被载入了,那么 Hibernate 就对该对象调用 lock() 方法。
2:如果指定的锁定模式是 READ,UPGRADE 或 UPGRADE_NOWAIT,那么 Session.lock() 就执行版本号检查。(在 UPGRADE 或者 UPGRADE_NOWAIT 锁定模式下,执行 SELECT ... FOR UPDATE这样的SQL语句。)
3:如果数据库不支持用户设置的锁定模式,Hibernate 将使用适当的替代模式(而不是扔出异常)。这一点可以确保应用程序的可移植性。
 

© 著作权归作者所有

共有 人打赏支持
乐在克里特
粉丝 15
博文 268
码字总数 394729
作品 0
杭州
程序员
注意Hibernate4在开发当中的一些改变

注意Hibernate4在开发当中的一些改变 Hibernate4的改动较大只有spring3.1以上版本能够支持,Spring3.1取消了HibernateTemplate,因为Hibernate4的事务管理已经很好了,不用Spring再扩展了。这...

千江
2013/05/24
0
1
hibernate4无法保存数据

初次使用hibernate4,使用getCurrentSession保存对象时无法将对象的数据保存进数据库,经过一番试验后,发现原来要配置事务才能保存数据。 保存数据失败原因: 没有配置事务,通过手动写一个...

heiyexue
2014/08/18
0
0
注意Hibernate4在开发当中的一些改变

Hibernate4的改动较大只有spring3.1以上版本能够支持,Spring3.1取消了HibernateTemplate,因为Hibernate4的事务管理已经很好了,不用Spring再扩展了。这里简单介绍了hibernate4相对于hiber...

Ida62
2014/03/13
0
0
注意Hibernate4在开发当中的一些改变

Hibernate4的改动较大只有spring3.1以上版本能够支持,Spring3.1取消了HibernateTemplate,因为Hibernate4的事务管理已经很好了,不用Spring再扩展了。这里简单介绍了hibernate4相对于hiber...

山海经
2014/03/22
0
0
Hibernate4实战 之第五部分:Hibernate的事务和并发

Hibernate本身没有事务的实现 Hibernate 直接使用 JDBC 连接和 JTA 资源,不添加任何附加锁定行为。也就是说你在Hibernate里面使用的事务要么是JDBC的事务,要么是JTA的事务。 Hibernate不锁...

jinnianshilongnian
2012/06/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

idea 通过jpa自动生成实体类

引入jpa包 打开persistence窗口 右键选择连接数据库 如果数据库没配置,则可以在下图选项中配置 选择好数据库和实体类的生成地址

斩神魂
31分钟前
1
0
tcpdump 命令

TCPDUMP简介 tcpdump 是一个很常用的网络包分析工具,可以用来显示通过网络传输到本系统的 TCP/IP 以及其他网络的数据包。tcpdump 使用 libpcap 库来抓取网络报,这个库在几乎在所有的 Linu...

寰宇01
38分钟前
2
0
软件的Alpha、Beta、RC、GA版本的区别

Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用。 Beta:也是测试版,这个阶段的版本会一直加入新的功能。在Alpha版之后推出。 RC:(Release Candidate) 顾名思义...

乔老哥
40分钟前
3
0
慢雾安全海贼王:从DApp亡灵军团,细说区块链安全

本文转载自微信公号“万向区块链”,为慢雾安全负责人海贼王在万向区块链实验室举办的2018上海区块链国际周-技术开放日上的演讲速记整理。 这张图总结了智能合约攻防的各个方面,分为两大部分...

万向区块链
45分钟前
14
0
Matlab编程之——卷积神经网络CNN代码解析

卷积神经网络CNN代码解析 deepLearnToolbox-master是一个深度学习matlab包,里面含有很多机器学习算法,如卷积神经网络CNN,深度信念网络DBN,自动编码AutoE ncoder(堆栈SAE,卷积CAE)的作...

酒逢知己千杯少
46分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部