从多个线程修改休眠实体 [英] Modifying hibernate entities from multiple threads

查看:88
本文介绍了从多个线程修改休眠实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解Hibernate中的线程安全细节时遇到了问题. 我知道Hibernate Sessions本身不是线程安全的,因此我不会从多个线程访问它们.但是,我找不到有关Hibernate实体的线程安全性的任何信息.我可以在它们仍附加到用于加载它们的会话的同时,在多个线程中对其进行修改吗?

I've got a problem with understanding the details of thread safety in Hibernate. I know that Hibernate Sessions are not by themselves thread safe, so I'm not going to access them from more than one thread. However, I can't find any information on the thread safety of Hibernate entities. Can I modify them in multiple threads, while they remain attached to the Session which was used to load them?

我不会使用延迟加载(我知道这会导致并发问题). 实体将被正确同步,并且休眠将通过同步的getter访问它们.

I won't be using lazy loading (I know it would lead to concurrency problems). Entities will be properly synchronized and hibernate will access them via synchronized getters.

我设想的场景:

  • 使用休眠会话从数据库加载实体A,
  • 随后,从加载实体的线程之外的多个线程修改实体A,
  • 实体A始终保持附着于 会话,并且处于持久状态,
  • 刷新会话,使修改与数据库同步.
  • 实体A仍保留在会话上,因此可以重复进行该循环,并进行进一步的修改和刷新.
  • Use a Hibernate Session to load entity A from database,
  • Subsequently, modify entity A from multiple threads, other than the thread in which the entity was loaded,
  • All the time entity A remains attached to the Session and is in persistent state,
  • Flush the Session so that modifications are synchronized with the database.
  • Entity A remains attached to the Session, so the cycle can repeat, with further modification and flushing.

推荐答案

这取决于修改的性质.如果您通过在另一个线程中创建,持久化另一个实体并将其与之关联来修改一个实体,那么它将无法正常工作,因为另一个实体实例将被视为在第一个线程中是分离的.

That depends on the nature of the modifications. If you modify an entity by creating, persisting and associating another entity with it in another thread, then it will not work, because the other entity instance will be considered detached in the first thread.

除了上面的用例之外,从理论上讲,这应该是可行的,并且仅当您不使用字节码检测进行脏检查时才行. Hibernate只会在需要刷新对象时检查它们是否脏;基本上,它并不关心您如何修改对象.

Taken aside the use cases like the one above, this should work in theory and only if you don't use bytecode instrumentation for the dirty check. Hibernate will just check whether the objects are dirty when they need to be flushed; basically, it does not care how you modified the objects.

但是,不建议这样做.

首先,它可能与Hibernate/JPA的未来版本不兼容(可能存在更多限制,阻止并发访问实体).

Firstly, it may not be compatible with future versions of Hibernate/JPA (there may be more restrictions preventing concurrent access to the entities).

第二,解决方法非常简单:只需为要同时修改的数据制作DTO,将其提交进行处理,并在处理完成后更新实体.这样,代码就更清晰了,不会出现与Hibernate线程有关的意外投诉,并且您可以灵活地使用其他有用的功能,例如延迟加载.

Secondly, the workaround is fairly simple: Just make the DTOs for the data that you want to modify concurrently, submit it for processing, and update the entities when the processing is done. This way the code is more clear, there are no unexpected Hibernate thread-related complaints and you keep the flexibility to use other useful features like lazy-loading.

这篇关于从多个线程修改休眠实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆