当前位置: 首页 > 知识库问答 >
问题:

从多个线程修改hibernate实体

房学
2023-03-14

我在理解Hibernate中线程安全的细节时遇到了问题。我知道Hibernate会话本身不是线程安全的,所以我不会从多个线程访问它们。但是,我找不到任何有关Hibernate实体的线程安全的信息。我可以在多个线程中修改它们,而它们仍然连接到用于加载它们的会话吗?

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

我设想的情景是:

  • 使用Hibernate会话从数据库加载实体A,
  • 随后,从多个线程中修改实体A,除了加载实体的线程之外,
  • 实体A始终连接到会话并处于持久状态,
  • 刷新会话,使修改与数据库同步。
  • 实体A仍然附属于会话,因此循环可以重复,并进行进一步的修改和冲洗。

共有2个答案

公良莫希
2023-03-14

Hibernate实体与会话紧密集成,我非常确信,如果会话不是线程安全的,那么实体也不是线程安全的。

即使不考虑会话,实体也只是java bean,不是线程安全的。如果你比如说

在一个线程中设置从anA到anB的引用,并在第二个线程中更改anA的属性(或持久化实体)。无法保证第二个线程会看到第一个线程的更改。

所以不是:Hibernate实体不是线程安全的。

孔城
2023-03-14

这取决于修改的性质。如果通过在另一个线程中创建、持久化和关联另一个实体来修改实体,则该实体将不起作用,因为另一个实体实例将被视为在第一个线程中分离。

抛开上面的用例不谈,这在理论上应该是可行的,并且只有在不使用字节码检测进行脏检查的情况下。Hibernate只会在需要刷新对象时检查对象是否脏;基本上,它不关心您如何修改对象。

但是,不建议这样做。

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

其次,解决方法相当简单:只需为要同时修改的数据创建DTO,将其提交处理,并在处理完成后更新实体。这样代码更加清晰,不会有意外的Hibernate线程相关的抱怨,并且您可以灵活地使用其他有用的功能,如懒惰加载。

 类似资料:
  • 问题内容: 我在了解线程安全的详细信息时遇到了问题。我知道这本身并不是线程安全的,所以我不会从多个线程访问它们。但是,我找不到有关Hibernate实体的线程安全性的任何信息。我可以在多线程中修改它们,而又仍然将它们附加到用于加载它们的会话中吗? 我不会使用延迟加载(我知道这会导致并发问题)。实体将被正确同步,并且hibernate将通过同步的getter访问它们。 我设想的方案: 使用hiber

  • 问题内容: 我有一个类,其中每30秒从一个后台线程填充一个映射,然后有一个方法,该方法将由多个读取器线程调用以获取可用的实时套接字,该套接字使用相同的映射来获取此信息。 如您在以上课程中所见: 从每30秒运行一次的单个后台线程,我使用所有活动套接字填充map。 然后,从多个线程中,我调用方法给我一个可用的实时套接字,该套接字使用map获取所需的信息。 我上面的代码线程安全吗,所有阅读器线程都可以正

  • 问题内容: ConcurrentModificationException:当不允许对对象进行并发修改时,检测到该对象的并发修改的方法可能会抛出此异常。 上面是javadoc中的ConcurrentModificationException定义。 所以我尝试测试以下代码: 代码很简单。10个线程从arraylist对象中删除该元素。确保多个线程访问一个对象。但它运行正常。没有异常被抛出。为什么?

  • 问题内容: 在一个通过所有者ID将数据分为存储桶的流量应用程序中,我们应该使用一个内部将数据分成存储桶的存储,还是每个存储桶一个存储实例? 例如,我们有一个应用程序用户,他是多名运动员的教练。每个教练运动员都有零次或多次锻炼,并且教练可以同时查看一个或多个运动员的锻炼。 我们可以为所有运动员开设一家健身店;商店必须确保将所有数据分离到各个运动员桶中,并且每种商店方法都需要一个运动者参数。 或者,每

  • 问题内容: 我有的: 我有Hibernate实体,它包含许多非瞬态字段,包​​括集合。用户可以分别更新每个字段或一次更新某些字段。 多么大的挑战: 在处理程序中,我应该检查实体的哪个字段已更改: 出于安全性和通知原因,我想这样做。手段: 并非所有用户都可以修改所有字段 我应该在某些字段更改时以特定方式通知特定用户。 有什么问题: 我得到非常丑陋的代码。实际上,我遍历所有字段/集合和调用方法。 题:

  • 问题内容: 我在Qt工作,当我按下GO按钮时,我需要不断将软件包发送到网络并使用收到的信息修改界面。 问题是我在按钮中有一个,所以按钮永不结束,所以界面永不更新。我想在按钮中创建一个线程并将代码放在那里。 我的问题是如何从线程修改接口?(例如,如何从线程修改textBox? 问题答案: 关于Qt的重要一点是, 必须 仅从GUI线程(即主线程)使用Qt GUI。 这就是为什么执行此操作的正确方法是从