`
footman265
  • 浏览: 118947 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

Hibernate并发控制

    博客分类:
  • SSH
阅读更多

3.    多个事务并发引起的题:
3.1.        第一类丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。
3.2.        脏读:一个事务读到另一个事务未提交的更新数据。
3.3.        幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
3.4.        不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。
3.5.        第二类丢失更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据。
4.    事务隔离级别:
为了解决多个事务并发会引发的问题。数据库系统提供了四种事务隔离级别供用户选择。
Serializable:串行化。隔离级别最高
Repeatable Read:可重复读。
Read Committed:读已提交数据。
Read Uncommitted:读未提交数据。隔离级别最差。

表9-2 事务隔离与隔离级别的关系

隔 离 级 别

脏读(Dirty Read)

不可重读(Unrepeatable read)

幻读(Phantom Read)

读操作未提交(Read Uncommitted)

可能

可能

可能

读操作已提交(Read Committed)

不可能

可能

可能

可重读(Repeatable Read)

不可能

不可能

可能

可串行化(Serializable)

不可能

不可能

不可能


数据库系统采用不同的锁类型来实现以上四种隔离级别,具体的实现过程对用户是透明的。用户应该关心的是如何选择合适的隔离级别。
对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读,而且具有较好的并发性能。
每个数据库连接都有一个全局变量@@tx_isolation,表示当前的事务隔离级别。JDBC数据库连接使用数据库系统默认的隔离级别。在Hibernate的配置文件中可以显示地设置隔离级别。每一种隔离级别对应着一个正整数。
Read Uncommitted: 1
Read Committed: 2
Repeatable Read: 4
Serializable: 8

在hibernate.cfg.xml中设置隔离级别如下:


    <session-factory> 
<!-- 设置JDBC的隔离级别 --> 
<property name="hibernate.connection.isolation">2</property> 
</session-factory>

设置之后,在开始一个事务之前,Hibernate将为从连接池中获得的JDBC连接设置级别。需要注意的是,在受管理环境中,如果Hibernate使用的数据库连接来自于应用服务器提供的数据源,Hibernate不会改变这些连接的事务隔离级别。在这种情况下,应该通过修改应用服务器的数据源配置来修改隔离级别。
5.    并发控制:
当数据库系统采用Red Committed隔离级别时,会导致不可重复读和第二类丢失更新的并发问题,在可能出现这种问题的场合。可以在应用程序中采用悲观锁或乐观锁来避免这类问题。
5.1.       乐观锁(Optimistic Locking)
乐观锁假定当前事务操纵数据资源时,不会有其他事务同时访问该数据资源,因此不作数据库层次上的锁定。为了维护正确的数据,乐观锁使用应用程序上的版本控制(由程序逻辑来实现的)来避免可能出现的并发问题
唯一能够同时保持高并发和高可伸缩性的方法就是使用带版本化的乐观并发控制。版本检查使用版本号、 或者时间戳来检测更新冲突(并且防止更新丢失)。
5.1.1.       使用版本检查(<version>):
Hibernate中通过版本号检查来实现后更新为主,这也是Hibernate推荐的方式。在数据库表中加入一个version(版本)字段,在读取数据时连同版本号一起读取,并在更新数据时比较版本号与数据库表中的版本号,如果等于数据库表中的版本号则予以更新,并递增版本号,如果小于数据库表中的版本号就抛出异常。
使用<version>进行版本控制的步骤:
1)      在持久化类中定义一个代表版本号的属性:

package org.qiujy.domain.versionchecking; 
  
import java.util.Date; 
  
public class Product implements java.io.Serializable{ 
       private Long id ; 
       /** 版本号 */ 
       private int version; 
       private String name; //产品名 
       private String description; //描述--简介 
       private Double unitCost; //单价 
       private Date pubTime; //生产日期 
       
       public Product(){} 
  
       //以下为getter()和setter()方法 
}

 
2)      在Product.hbm.xml文件中用<version>元素来建立Product类的version属性与表中version字段的映射。

3)      Hibernate在其数据库访问引擎中内置了乐观锁定实现,默认也是选择version方式作为Hibernate乐观锁定实现机制。所以,在配置文件及程序中可以不作其它设置。按往常一样写操作代码。

 

新增数据时产生的SQL是:


package org.qiujy.domain.versionchecking; 
  
import java.util.Date; 
  
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction; 
import org.qiujy.common.HibernateSessionFactory; 
  
public class TestVersionChecking { 
       
       public static void main(String[] args) { 
              Product prod = new Product(); 
              prod.setName("IBM thinkPad T60"); 
              prod.setUnitCost(new Double(26000.00)); 
              prod.setDescription("笔记本电脑"); 
              prod.setPubTime(new Date()); 
              
              //test start....... 
              Session session = HibernateSessionFactory.getSession(); 
              Transaction tx =null; 
              try{ 
                     tx = session.beginTransaction(); 
                     
                     session.save(prod); 
                 
                    tx.commit(); 
              }catch(HibernateException e){ 
                     if(tx != null){ 
                            tx.rollback(); 
                     } 
                     e.printStackTrace(); 
              }finally{ 
                     HibernateSessionFactory.closeSession(); 
              } 
        
//进行更新 测试.. 
              prod.setDescription("新款的"); 
              
              Session session2 = HibernateSessionFactory.getSession(); 
              Transaction tx2 =null; 
              try{ 
                     tx2 = session2.beginTransaction(); 
                     
                     session2.update(prod); 
                
                    tx2.commit(); 
              }catch(HibernateException e){ 
                     if(tx2 != null){ 
                            tx2.rollback(); 
                     } 
                     e.printStackTrace(); 
              }finally{ 
                     HibernateSessionFactory.closeSession(); 
              } 
       } 
}

insert into products (version, name, description, unitCost, pubTime) 
    values(?, ?, ?, ?, ?)


程序无需为Product对象的version属性显示赋值,当持久化一个Product对象时,Hibernate会自动为它赋初始值为0。
更新数据时产生的SQL是:


    update 
        products 
    set 
        version=?, 
        name=?, 
        description=?, 
        unitCost=?, 
        pubTime=? 
    where 
        id=? 
        and version=?


当Hibernate更新一个Product对象,会根据它的id和version属性到相应的数据库表中定位匹配的记录,如果存在这条匹配的记录,就更新记录,并且把version字段的值加1。若找不到匹配的记录,此时Hibernate会抛出StaleObjectStateException。
 

需要注意的是,由于乐观锁定是使用系统中的程序来控制,而不是使用数据库中的锁定机制,因而如果有人故意自行更新版本信息来超过检查,则锁定机制就无效。所以建议把持久化类中的version的get方法设置为private的。
5.1.2.       使用时间戳(<timestamp>):
跟版本检查的用法相似。不再多说。
5.2.       悲观锁(Pessimistic Locking)
悲观锁假定当前事务操纵数据资源时,肯定还会有其他事务同时访问该数据资源,为了避免当前事务的操作受到干扰,先锁定资源。尽管悲观锁能够防止丢失更新和不可重复读这类并发问题,但是它影响并发性能,因此应该很谨慎地使用悲观锁。 

 

 

分享到:
评论

相关推荐

    Hibernate事务和并发控制

    事务和并发控制是数据库管理中的核心概念,特别是在使用ORM框架如Hibernate时,理解它们的工作原理至关重要。本文将深入探讨Hibernate中的事务管理和并发控制。 首先,事务是数据库操作的基本单位,它保证了数据的...

    Hibernate 事务和并发控制

    本文将深入探讨Hibernate中的事务和并发控制,这对于开发高效、稳定的数据库应用至关重要。 首先,我们来理解Hibernate中的事务管理。在数据库操作中,事务是保证数据一致性的重要手段。一个事务包含了一组数据库...

    Hibernate中,利用版本管理机制来控制事务并发

    在Java的持久化框架Hibernate中,版本管理机制是实现事务并发控制的重要手段。它通过维护对象的版本信息,确保在多线程环境下数据的一致性和完整性。本文将深入探讨Hibernate中的版本管理机制及其在控制事务并发中的...

    Hibernate part 14:查询及数据库并发事务

    5. **乐观锁与悲观锁**:Hibernate提供了这两种并发控制策略。乐观锁假设冲突较少,只在提交时检查版本号;悲观锁则在读取数据时就进行锁定,防止其他事务修改。 6. **事务管理**:在Hibernate中,可以通过编程式...

    hibernate事务,并发及缓存管理实例

    在Hibernate中,事务、并发控制和缓存管理是至关重要的概念,它们极大地影响了应用程序的性能和数据一致性。 一、Hibernate事务管理 在数据库操作中,事务确保了数据的一致性和完整性。Hibernate提供了四种事务隔离...

    java socket 多线程并发控制 hibernate mysql

    本项目聚焦于使用Java的Socket进行多线程并发控制,并结合Hibernate ORM框架与MySQL数据库进行数据存储。下面将详细阐述这些技术及其应用。 首先,Java Socket是Java提供的用于实现网络上不同计算机间进程通信的...

    Hibernate4实战 之第五部分:Hibernate的事务和并发

    Hibernate 通过版本字段实现自动乐观并发控制。 2. **悲观锁(Pessimistic Locking)**:假设数据冲突很常见,因此在数据读取时即锁定数据,直至事务完成。Hibernate 支持行级悲观锁,通过 SQL 的 `SELECT FOR UPDATE...

    hibernate的事务核并发

    标题:“Hibernate的事务与并发控制” 描述:本文深入解析了Hibernate框架中事务管理和并发控制的核心概念及其实现机制,基于一份详尽的“hibernate详细解析.pdf”文档,覆盖了非托管环境、JTA环境下的事务处理以及...

    Hibernate教程26_事务并发处理

    在多用户同时访问数据库时,事务并发控制就显得尤为重要,以防数据冲突和不一致。 悲观锁是假设最坏的情况,即每次读取数据时都假设会有其他用户同时尝试修改。因此,悲观锁会在数据读取时立即加上锁,直到事务结束...

    java面试题

    17. **Hibernate并发控制**: - 通过设置事务隔离级别防止并发问题。 - 隔离级别包括:`Serializable`(串行化)、`Repeatable Read`(可重复读)、`Read Committed`(已提交读)和`Read Uncommitted`(未提交读)...

    J2EE事务并发控制策略总结汇编.pdf

    在J2EE应用中,事务并发控制策略对于确保数据的一致性和完整性至关重要。本文主要围绕J2EE环境下的持久层设计,特别是针对事务并发访问控制进行总结。事务并发访问控制分为两类:同一系统事务内的并发控制和跨系统...

    优化Hibernate性能的几点建议

    例如,通过Spring管理Hibernate的Session和Transaction,可以更加灵活地控制事务边界,提高系统的可维护性和扩展性。 总之,优化Hibernate性能是一个复杂的过程,涉及到配置调整、编码习惯、以及对数据库的深入了解...

    课程hibernate的事务和并发.pdf

    《课程hibernate的事务和并发》主要探讨了在Hibernate框架中如何管理和处理事务以及并发控制。Hibernate作为一款流行的Java ORM(对象关系映射)工具,其事务处理和并发控制策略对于开发高效、稳定的数据库应用至关...

    Hibernate事务控制[定义].pdf

    Hibernate默认禁用了数据库的自动提交模式,因为在实际应用中,我们希望控制事务的边界,以便更好地管理并发和错误处理。 通常推荐每个HTTP请求或业务逻辑单元对应一个Session和一个事务。这样可以确保事务的生命...

    Web应用中并发控制的实现.pdf

    在Web应用中,并发控制是确保数据一致性与正确性的关键技术。随着B/S架构的广泛应用,比如电商系统、售票系统等,并发问题愈发突出。在传统的C/S架构中,长事务处理可以有效解决并发问题,但在Web环境中,由于HTTP...

    学习J2EE事务并发控制策略总结.pdf

    在J2EE应用程序中,事务并发控制策略是确保系统稳定性与数据一致性的重要组成部分。这篇文章主要聚焦于J2EE环境中持久层的设计挑战,特别是如何处理事务的并发访问。它提到了几种常见的并发控制策略,包括乐观锁和...

    hibernate的事务和并发资料.pdf

    《Hibernate的事务和并发资料》深入探讨了在Java应用程序中使用Hibernate进行事务管理和并发控制的关键概念。Hibernate作为一款流行的ORM框架,它简化了与数据库的交互,但同时也需要开发者理解其背后的事务处理机制...

Global site tag (gtag.js) - Google Analytics