在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>