`

Hibernate在应用层对并发事务的控制

阅读更多

摘抄:http://chillwarmoon.iteye.com/blog/100848

 

Hibernate与事务处理一文中,介绍了事务以及并发事务处理时的问题,和针对于这些问题在数据库层所能做的隔离级别,但是在选择read commit和repeatable read两个隔离级别时,如果考虑到performance和scalability,可以选择一个折衷的方案,也就是在数据库中的隔离级别选择read commit,而通过对应用程序的控制,可以达到repeatable read的效果。Hibernate在程序中控制并发的事务处理上,也有自己的方法,本文在Hibernate与事务处理基础上,对Hibernate的这些并发事务处理方法进行介绍。
数据库隔离级别可以通过设置hibernate的属性文件,来改变数据库默认的隔离级别:
xml 代码
  1. 1:Read umcommited  
  2. 2:Read commited  
  3. 3:Repeatable read  
  4. 4:Serializable  

在这里设置hibernate.connection.isolation=2;但需要注意的是,如果hibernate用在了应用服务器上,该应用服务 器对数据库连接提供了受管理的控制,则这里设置的isolation级别失效,采用的是app server定义的级别,可以通过改变app server的配置来改变该隔离级别。
因为这里设置的隔离级别是read commit,那如果想达到repeatable read,则需要设置version number或者timestamp。

如果某个项目从头到尾开始设计和开发,考虑到事务处理,则在需要并发控制的数据库表字段上,添加和hibernate的version number相对应的字段。例如对Student表的并发控制,则需要在TSTUDENT表上添加STU_VERSION字段,在ORM的映射文件中需要在标识符属性下添加,例如:
java 代码
 
  1. <class name="Student" table="TSTUDENT">  
  2. ...  
  3. <!---->class>  

在Student.java的pojo文件中添加:
java 代码
 
  1. public class Student {  
  2. ....  
  3. private int version;  
  4. ...  
  5. }  

version属性是不能被应用所改变的,所以仅仅提供get方法即可。但是version number是怎样在应用层提供对事务的并发处理机制呢?原理是这样的:在hibernate的事务A(在这里假设事务的范围和Session范围一致,每个Session对应一个persistent context)中,执行每一个DML操作,都会先检查一下对象的version属性,假如从数据库中得到的student实例的version属性是1,此时student已经加载到Session对应的persistent context中,如果对student对象进行改变,在Session.flush()的时候,则将persistent context中的student对象的version属性设置为2,然后在保存student对象时,将对象对应的记录version字段更新为2。
注意的是,如果并发的另一个事务B在事务A进行保存操作之前,已经将version更新为2或者更高值的student存入数据库,那A在保存student之前,需要检查该persistent object对应的记录的version为1(因为在从数据库取得persistent object的时候,version为1)的行的个数,如果行数为0,则抛出 StaleObjectStateException,表明存在其他的事务更新了数据库,那这样的话,A事务的更新操作就不会覆盖B事务的更新操作,达到了避免(3)问题中的second lost update(见Hibernate与事务处理)。
当然避免了second lost update是不够的,因为是不是这样就能够具有repeatable read的隔离级别呢?比较一下read commit和repeatable read的隔离级别的差别,read commit是读事务允许其他事务并发执行,而repeatable read是读事务不允许写事务并发执行,在hibernate中,通过Session对应的persistent context来实现后者,具体是在一个事务A中(假设事务的范围和Session范围一致),读取student对象到persistent context,此时事务B更改了student对象对应的记录并进行持久化,根据数据库的默认隔离级别read commit,那么A事务如果再读取student对象,那就是产生unrepeatable read,其实不然,正是因为hibernate的persistent context,使得A事务再次读取student不是从数据库中读取,而是从当前的Session读取,因此避免了unrepeatable read,同时使得具有类似于数据库隔离级别repeatable read的隔离效果。

当然我们这里假设的是事务的范围和Session范围一致,但是当用户操作中途停留时间过长,则需要将不同的事务在同一conversation下实现,要保证不同事务共用Session可以通过Hibernate的FlushMode来实现。当然也可以保证Session和事务的对应,通过在不同Session中传递detached object来实现。

对于Hibernate在应用层对并发事务的控制方法还有timestamp,pessimistic locking,这里先不做介绍。
分享到:
评论

相关推荐

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    Hibernate实战(第2版 中文高清版)

     10.1.2 Hibernate应用程序中的事务   10.1.3 使用Java Persistence的事务   10.2 控制并发访问   10.2.1 理解数据库级并发   10.2.2 乐观并发控制   10.2.3 获得额外的隔离性保证   10.3 非事务数据...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    hibernate 教程

    乐观并发控制(Optimistic concurrency control) 10.4.1. 使用长生命周期带有自动版本化的会话 10.4.2. 使用带有自动版本化的多个会话 10.4.3. 应用程序自己进行版本检查 10.5. 会话断开连接(Session...

    hibernate

    乐观并发控制(Optimistic concurrency control) 10.4.1. 使用长生命周期带有自动版本化的会话 10.4.2. 使用带有自动版本化的多个会话 10.4.3. 应用程序自己进行版本检查 10.5. 会话断开连接(Session...

    低清版 大型门户网站是这样炼成的.pdf

    5.9 hibernate应用的性能优化 336 5.10 多数据源的应用 338 5.11 jdbc的应用 343 5.12 hibernate调用存储过程 343 5.13 xml数据持久化 346 5.14 小结 348 第6章 充分利用spring 2.5的ioc利器统管bean世界 349 ...

    Spring3.x企业应用开发实战(完整版) part1

     《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

    Spring.3.x企业应用开发实战(完整版).part2

     《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    该案例采用目前最流行、最规范的java ee架构,整个应用分为jpa实体层、eao层、业务逻辑层、mvc层和视图层,各层之间分层清晰,层与层之间以松耦合的方法组织在一起。该案例既提供了ide无关的、基于ant管理的项目源码...

    java面试题

    答:声明式的事务管理主要是将在进行对数据库中数据的添加或者修改时需要执行事务管理,主要是为了避免在执行添加或修改的时候添加或修改不完全正确,导致数据丢失。spring使用AOP面向切面的思想进行事务管理的。 ...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    由于B/S架构管理软件只安装在服务器端(Server)上,即应用程序在部署、升级、维护时,只需要在服务器端进行配置就可以了,网络管理人员只需要管理服务器就行了,用户界面主要事务逻辑在服务器(Server)端完全通过...

    从J2SE到J2EE知识点介绍

    5. Hibernate的事务与并发 238 (十) 数据库 240 1. 数据库的基本概念 240 2. 数据模型 240 3. 关系模型 241 数据流图(Data Flow Diagram,DFD) 241 E-R图 241 4. 关系规范化 242 5. Mysql 的安装 243 6. Transact-SQL...

    iBATIS实战

    7.6.3 将事务在业务逻辑层划界 128 7.7 小结 129 第8章 使用动态SQL 130 8.1 处理动态WHERE子句条件 130 8.2 熟悉动态标签 132 8.2.1 dynamic标签 134 8.2.2 二元标签 135 8.2.3 一元标签 136 8.2.4 参数标签 137 ...

    基于J2EE框架的个人博客系统项目毕业设计论...

    由于B/S架构管理软件只安装在服务器端(Server)上,即应用程序在部署、升级、维护时,只需要在服务器端进行配置就可以了,网络管理人员只需要管理服务器就行了,用户界面主要事务逻辑在服务器(Server)端完全通过...

    Java常见面试题208道.docx

    123.在 hibernate 中 getCurrentSession 和 openSession 的区别是什么? 124.hibernate 实体类必须要有无参构造函数吗?为什么? 十三、Mybatis 125.mybatis 中 #{}和 ${}的区别是什么? 126.mybatis 有几种分页方式...

    JAVA上百实例源码以及开源项目

     关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥...

    java开源包1

    GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet....

Global site tag (gtag.js) - Google Analytics