Java 休眠中的并发更新处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3616321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 02:42:51  来源:igfitidea点击:

Concurrent updates handling in hibernate

javaoraclehibernatespring

提问by Rakesh Goyal

Presently we are using JDBC in the data layer and planning to replace it with hibernate. I am new to Hibernate and not sure how hibernate handles concurrency. Can somebody explain me if we use spring for the transaction management, how concurrent updates will be handled: by hibernate (In memory automatic version management of hibernate) or I have to put version column in the database to take care of concurrent updates manually.

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

采纳答案by Pascal Thivent

Can somebody explain me if we use spring for the transaction management, how concurrent updates will be handled by hibernate (In memory automatic version management of hibernate) or I have to put version column in the database to take care of concurrent updates manually.

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

Whether you're using Spring for transaction management or not doesn't really matter and isn't relevant when it comes to concurrency management, this is actually handled by Hibernate. Hibernate can use 2 strategies to handle concurrent updates: optimistic locking and pessimistic locking.

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

Optimistic

乐观的

When using optimistic locking, you map a special attribute (a number, a timestamp) as a version(so you actually have a column for it). This version is read when you retrieve an entity and includedin the where clause during an update and incrementedby Hibernate.

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

To illustrate how this works, let's imagine you load a Person entity by id=1 and with a current version=1. After a save, Hibernate will perform something like this:

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

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

So, now, imagine you have two concurrent transactions running, each of them loading the sameentity (same version number) and changing the name.

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

Let's say transaction #1 is committed first, the following query is performed:

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

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

It succeeds and the version gets incremented.

它成功并且版本增加。

Then transaction #2 is committed, the following query is performed:

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

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

This one won't update anything because the where clause won't match any record. This is where you'll get an optimistic concurrency exception.

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

This strategy is appropriate when you don't maintain the connection, when concurrent accesses are not frequent, and scales really well. And everything is of course handled transparently by Hibernate for you, as long as you map a version attribute.

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

Pessimistic

悲观

When using pessimistic locking, Hibernate locks a record for your exclusive use until you have finished with it (typically using a SELECT ... FOR UPDATE). Any other concurrent transaction trying to access the same record will get suspended until the lock is removed. This strategy gives better predictability, at the price of performance and doesn't scale indefinitely.

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

References

参考

回答by Lars Andren

Hibernate handles the versioning on its own, a healthy suggestion is to not tamper with the version number at all.

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

More on versioning in Hibernate

更多关于 Hibernate 中的版本控制

A general but simple guide

一般但简单的指南

回答by Bruno

There is some documentation about sessions and transactions on the Hibernate community wiki. It's ultimately handled by the underlying RDBMS transactions, but you need to pay attention to the life cycle of the objects loaded or saved.

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

回答by Chaitan Yadav

There are JPA implementations like objectDB in which optimistic locking is activated by default and user don't need to maintain version variable in database table as, it is internally taken care by objectDB. Optimistic locking is good where updates are not frequent and where locking have implicit costs like in e-commerce where locking means loss of business. Pessimistic locking is ideal where concurrency is not much demanded and transaction is finished quickly to free up the resource.

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