Hibernate中的乐观锁和悲观锁怎么理解?如何实现

在Hibernate中,乐观锁和悲观锁用于解决事务并发问题,实现数据一致性。区别如下:

乐观锁:

  • 假设数据不会被其他事务修改,在提交更新时再检查数据是否实际被修改。如果数据被修改,更新失败,事务回滚。
  • 实现方式:在需要乐观锁的表中增加版本字段(如version),每更新一次数据version值加1。更新数据时将最新version值置入WHERE条件,如果version值不匹配,说明数据被其他事务修改,更新失败。
    例如:
@Entity
@Table(name="customer")
public class Customer {
    @Id
    @GeneratedValue
    private Integer id;
    private String name;
    @Version 
    private Integer version;
}
Customer customer = session.get(Customer.class, 1);
customer.setName("John");
session.update(customer);   // WHERE id=? AND version=?  version加1

悲观锁:

  • 假设数据会被其他事务修改,在读取数据时就加锁,阻塞其他事务的修改,确保数据一致性。
  • 实现方式:在hibernate.cfg.xml中配置悲观锁机制,如SELECT … FOR UPDATE。当Hibernate执行查询语句时,会自动加上悲观锁关键字对记录加锁。
    例如:
<property name="hibernate.query.comments">true</property>
<property name="hibernate.query.passDistinctThrough">false</property>
<property name="hibernate.query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory</property> 
<property name="org.hibernate.query.comments">true</property>
<property name="org.hibernate.query.lockMode">LOCK</property>