JPA中的乐观锁和悲观锁是什么?如何实现和使用?代码举例讲解

JPA中的乐观锁和悲观锁用于实现并发控制。

乐观锁:

  1. 假设不会发生并发修改,只在提交事务时检查实体是否被其他事务修改。
  2. 通常使用版本字段和TIMESTAMP实现。每次更新时,版本会加1。提交事务时检查版本,如果与加载时不一致,则认为已被修改。
  3. 乐观锁可以提高并发性,但会产生回滚与重试的开销。

悲观锁:

  1. 假定会发生并发修改,在加载实体时就将其锁定。
  2. 其他事务的修改操作会被阻塞或抛出异常。
  3. 悲观锁可以避免修改冲突,但会较大影响性能与吞吐量。

实现方法:

  1. 版本字段:在实体上添加version字段,每次更新时使版本加1。
@Version
private int version;
  1. TIMESTAMP:使用TIMESTAMP字段存储上次修改时间。
@Column(name = "LAST_UPDATE_TIMESTAMP") 
private Timestamp lastUpdateTimestamp;
  1. 悲观锁:在事务中进行实体加载和修改操作。其他事务的修改会被阻塞。
    代码示例:
// 乐观锁 - 版本字段
@Entity
public class Product {
   @Id
   private int id;
   @Version 
   private int version;  
}

// 悲观锁
EntityManager em = emf.createEntityManager(); 
EntityTransaction tx = em.getTransaction();
tx.begin();  
Product product = em.find(Product.class, 1);  
// 修改 product
...  
tx.commit(); 
em.close();