hibernate中的并发更新处理

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

如果我们使用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子句不匹配任何记录。 这是您将获得乐观并发exception的地方。

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

悲观

当使用悲观锁定时,Hibernate会锁定一条记录供您独家使用,直到您完成它(通常使用SELECT ... FOR UPDATE )。 尝试访问同一记录的任何其他并发事务将被暂停,直到锁定被删除。 该策略以性能价格提供更好的可预测性,并且无法无限扩展。

参考

  • Hibernate核心参考指南
    • 11.3。 乐观的并发控制
    • 11.4。 悲观锁定

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

有一些关于Hibernate社区wiki上的会话和事务的文档 。 它最终由底层的RDBMS事务处理,但您需要注意加载或保存的对象的生命周期。

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

有关Hibernate版本控制的更多信息

一般而简单的指南