休眠中的并发更新处理

Posted

技术标签:

【中文标题】休眠中的并发更新处理【英文标题】:Concurrent updates handling in hibernate 【发布时间】:2011-04-06 16:34:05 【问题描述】:

目前我们在数据层使用 JDBC,并计划用 hibernate 替换它。我是 Hibernate 的新手,不确定 hibernate 如何处理并发。有人可以解释一下,如果我们使用 spring 进行事务管理,将如何处理并发更新:通过休眠(在内存中休眠的自动版本管理)或者我必须将版本列放入数据库中以手动处理并发更新。

【问题讨论】:

【参考方案1】:

Hibernate 自己处理版本控制,一个健康的建议是根本不要篡改版本号。

More on versioning in Hibernate

A general but simple guide

【讨论】:

【参考方案2】:

有一些documentation about sessions and transactions on the Hibernate community wiki。最终由底层的 RDBMS 事务处理,但需要注意加载或保存的对象的生命周期。

【讨论】:

【参考方案3】:

如果我们使用spring进行事务管理,有人可以解释一下,hibernate将如何处理并发更新(在内存中hibernate的自动版本管理)或者我必须将版本列放在数据库中以手动处理并发更新.

您是否使用 Spring 进行事务管理并不重要,也与并发管理无关,这实际上是由 Hibernate 处理的。 Hibernate 可以使用 2 种策略来处理并发更新:乐观锁定和悲观锁定。

乐观

当使用乐观锁时,你将一个特殊的属性(一个数字,一个时间戳)映射为一个版本(所以你实际上有一个列)。当您在更新期间检索实体并在 where 子句中 包含 并由 Hibernate 递增 时,将读取此版本。

为了说明这是如何工作的,让我们假设您加载一个 id=1 且当前版本=1 的 Person 实体。保存后,Hibernate 会执行如下操作:

update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;

现在,假设您有两个并发事务正在运行,每个事务都加载相同实体(相同版本号)并更改名称。

假设首先提交事务#1,执行以下查询:

update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;

成功,版本递增。

然后事务#2被提交,执行如下查询:

update PERSON set ID=1, NAME='NAME 2', VERSION=2 where ID=1 and VERSION=1;

这个不会更新任何内容,因为 where 子句不会匹配任何记录。这是您将获得乐观并发异常的地方。

当您不维护连接、并发访问不频繁且可扩展性非常好时,此策略是合适的。当然,Hibernate 会为您透明地处理一切,只要您映射版本属性。

悲观

当使用悲观锁定时,Hibernate 锁定一条记录供您独占使用,直到您完成它(通常使用SELECT ... FOR UPDATE)。任何其他试图访问同一记录的并发事务都将被挂起,直到锁被删除。这种策略以性能为代价提供了更好的可预测性,并且不会无限扩展。

参考文献

Hibernate 核心参考指南 11.3. Optimistic concurrency control 11.4. Pessimistic locking

【讨论】:

+1 for u man.. 但是告诉我一件事,在乐观锁定中谁会在声明中给出版本号。它的用户或休眠自动管理它。 当前关于 Hibernate 版本控制的文档在这里 docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html【参考方案4】:

有像 objectDB 这样的 JPA 实现,其中乐观锁定是默认激活的,用户不需要在数据库表中维护版本变量,因为它在内部由 objectDB 负责。乐观锁定适用于更新不频繁且锁定具有隐含成本的情况,例如在电子商务中锁定意味着业务损失的情况。悲观锁定是理想的并发性要求不高且事务快速完成以释放资源的情况。

【讨论】:

以上是关于休眠中的并发更新处理的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch:处理 Elasticsearch 中数据更新的并发

Elasticsearch:处理 Elasticsearch 中数据更新的并发

休眠保存或更新行为

使用@Query和休眠更新spring数据jpa中的布尔值

使用休眠和弹簧更新

使用更新事件进行休眠审计