hibernate悲观锁与乐观锁

2019-03-03 18:18|来源: 领悟书生

一般并发会导致更新丢失,有两种解决方案可以解决并发的问题

1、悲观锁

悲观锁是Hibernate基于数据库的机制来实现的,hibernate是基于同步的机制实现的,当只要读取了这个对象,这个对象就会被加锁

只有在第一个对象读取完成之后第二个对象才能读取。这样将会大大的影响效率

session = HibernateUtil.openSession();
session.beginTransaction();
//只要使用这种方式来load就会为其增加锁
Student stu = (Student)session.load(Student.class,1,LockOptions.UPGRADE);
stu.setName("李四1");
session.getTransaction().commit();


2、乐观锁

乐观锁是在数据库中增加一个version的字段来实现的,每一次修改都会让这个字段的数字加1,在读取的时候根据version这个版本数据来读取

这样如果并发修改就会抛出异常

例如给Student增加一个version字段

Student.java

public class Student {
    private int id;
    private String name;
    private String sex;
    private int version;//新添加
        ...
}

修改Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="org.zttc.itat.model">
    <class name="Student" table="t_stu">
        <id name="id">
            <generator class="native"/>
        </id>
        <!-- 一定要放在id之后 -->
        <version name="version"/>
        <property name="name"/>
        <property name="sex"/>
        <many-to-one name="classroom" column="cid" fetch="join"/>
    </class>
</hibernate-mapping>

Annotation的方式增加版本的方式如下:

@Entity
@Table(name="t_stu")
public class Student {
    ......
    private int version;
     
    @Version
    public int getVersion() {
        return version;
    }
    public void setVersion(int version) {
        this.version = version;
    }
         
        ......
}


这样每次更新的时候,都会更新版本的值

session = HibernateUtil.openSession();
session.beginTransaction();
Student stu = (Student)session.load(Student.class, 1);
stu.setName("李四1");
session.getTransaction().commit();



本文链接:hibernate悲观锁与乐观锁,领悟书生学习笔记,转载请注明出处:http://www.656463.com/article/423

相关问答

更多
  • 乐观锁是假设事务冲突很少发生 悲观锁则假设事务冲突经常发生
  • 保证数据安全,处理多用户并发访问。 悲观锁,锁如其名,他对世界是悲观的,他认为别人访问正在改变的数据的概率是很高的,所以从数据开始更改时就将数据锁住,知道更改完成才释放。 乐观锁,他对世界比较乐观,认为别人访问正在改变的数据的概率是很低的,所以直到修改完成准备提交所做的的修改到数据库的时候才会将数据锁住。完成更改后释放。 悲观锁会造成访问数据库时间较长,并发性不好,特别是长事务。 乐观锁在现实中使用得较多,厂商较多采用。
  • 1、悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系 统不会修改数据)。 2、乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。 ...
  • 悲观锁,就是不管是否发生多线程冲突,只要存在这种可能,就每次访问都加锁。 乐观锁,就是通过标记值控制,每次操作前通过标记值判断是否是最新内容,最新内容就可以操作,不是最新的就继续循环判断标记值,直到是最新类容。 在大量冲突发生时,悲观锁的锁消耗大,乐观锁的读取次数会多。
  • 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类 ...
  • 先申明概念: 1、悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。 2、乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程 ...
  • 为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突。为了解决这个问题,大多数数据库用的方法就是数据的锁定。 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁。什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住。而乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息,让用户决定如何去做。 先从悲观锁开 ...
  • 这是心态,对人对事乐观点好。。。 乐观的人心态开放,豪爽,所以越来越乐观;悲伤的人觉得自己一无
  • 关于mysql中的乐观锁和悲观锁面试的时候被问到的概率还是比较大的。 mysql的悲观锁: 其实理解起来非常简单,当数据被外界修改持保守态度,包括自身系统当前的其他事务,以及来自外部系统的事务处理,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制,但是也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在自身系统中实现了加锁机制,也无法保证外部系统不会修改数据。 来点实际的,当我们使用悲观锁的时候我们首先必须关闭mysql数据库的自动提交属性,因为MyS ...
  • 嗯。Hibernate还有一个是乐观锁。就是如同SVN一样。是对数据增加版本号。如果版本号匹配。哪么就更新。如果不匹配就出异常。嗯。