Hibernate 提供了多种机制来应对并发更新导致的数据不一致问题,主要包括以下几种:
1. 乐观锁(Optimistic Locking)
原理:
示例:
@Version
private int version;
工作流程:
适用场景:
- 读多写少、冲突概率低的应用场景。
2. 悲观锁(Pessimistic Locking)
原理:
- 假设并发冲突频繁发生,每次读取数据时就加锁,阻止其他事务读或写。
- Hibernate 提供
LockMode
(如PESSIMISTIC_WRITE
)实现数据库级锁。
示例:
Session session = entityManager.unwrap(Session.class);
session.get(User.class, userId, LockMode.PESSIMISTIC_WRITE);
工作流程:
- 查询数据时加锁,直到事务结束,其他事务只能等待或失败。
适用场景:
- 冲突概率高、对数据一致性要求高的应用,如金融、库存系统。
3. 数据库事务隔离级别
Hibernate 依赖底层数据库的事务隔离机制(如 READ COMMITTED、REPEATABLE READ、SERIALIZABLE)来避免脏读、不可重复读和幻读。
- 可以通过 Hibernate 配置设置事务隔离级别:
hibernate.connection.isolation = 4 # 对应 Connection.TRANSACTION_REPEATABLE_READ
4. 应用层重试机制
结合乐观锁机制,遇到版本冲突时可以捕获异常并自动重试:
int retries = 3;
while (retries-- > 0) {
try {
// 加载实体、修改、提交事务
break;
} catch (OptimisticLockException e) {
// 重试逻辑
}
}
小结
机制 | 是否加锁 | 优点 | 缺点 |
---|---|---|---|
乐观锁 | 否 | 性能高,适合读多写少 | 冲突时可能多次重试 |
悲观锁 | 是 | 保证强一致性 | 性能较差,容易产生死锁 |
事务隔离级别 | 底层机制 | 数据库直接控制并发 | 可配置性有限,开销大 |