Hibernate 与 Grails 数据库操作及优化
1. 乐观锁与悲观锁
在数据库操作中,为了处理并发访问问题,Hibernate 提供了悲观锁和乐观锁两种机制。
1.1 悲观锁
Hibernate 通过 Session.lock() 方法支持悲观锁,其中 LockMode.PESSIMISTIC_WRITE 是常用的模式,它会执行 select ... for update 查询,将行数据排他锁定。不过,这种锁定必须在事务中进行,并且通常只有在事务提交或回滚时才会释放,这可能会导致性能问题和锁争用风险。
1.2 乐观锁
乐观锁不使用数据库锁,而是尝试检测并发编辑是否发生。Hibernate 的做法是为每行数据添加一个版本列,通常是一个序列号,也可以是时间戳,但使用时间戳时,在快速机器上如果两个更新在同一毫秒发生,可能会有极小概率无法检测到冲突。
当两个用户获取版本号为 N 的行数据并进行不同修改后保存时,第二个用户的更改会覆盖第一个用户的更改。为了检测这种情况,生成的更新 SQL 会类似如下形式:
update <table name> set <col1>=?, <col2>=?, ... where id=? and version=?
如果在记录获取和更新之间版本号发生了变化,更新将不会执行(更新的行数为 0),这表明发生了并发修改,会抛出 Stale
超级会员免费看
订阅专栏 解锁全文
32

被折叠的 条评论
为什么被折叠?



