Hibernate悲观锁(pessimistic lock)实例详解

Hibernate支持悲观锁,通过@Lock注解和LockModeType枚举指定锁定策略。下面是一个例子:

@Entity
public class Product {
    @Id
    private Integer id;
    private String name;
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    private int quantity;
}

这里我们在quantity字段上添加了@Lock(LockModeType.PESSIMISTIC_WRITE),表示在更新quantity字段时获得写锁。然后在service中:

@Transactional
public void updateQuantity(int productId, int quantity) {
    Product product = em.find(Product.class, productId);
    product.setQuantity(quantity);
    em.flush();  //手动flush,否则lock不会起作用
}

当两个线程同时调用这个方法更新一个Product的quantity时:- 第一个线程在em.find()时会获得写锁

– 第二个线程在em.find()时会等待第一个线程释放锁

– 第一个线程执行完commit后释放锁,第二个线程获得锁,开始更新并提交这样就实现了悲观锁的效果,确保数据更新的原子性。Hibernate还支持@Version来实现乐观锁,两者可以根据需要搭配使用。除@Lock注解外,我们也可以在Session级别设置锁模式:

Session session = em.unwrap(Session.class);
session.doWork(new AbstractWork() {
    @Override
    public void execute(Connection conn) {
        Session sess = sessionFactory.openSession(conn);
        Transaction tx = sess.beginTransaction();
        Product product = sess.load(Product.class, productId, 
            LockMode.PESSIMISTIC_WRITE);
        //.....
    } 
});
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论