java - Hibernate SaveOrUpdate - 多个工作线程

标签 java database hibernate

虽然我已经能够找到有关 Hibernate 事务如何工作的信息,因此数据库不会损坏,但更难理解 Hibernate 如何处理在线程之间共享的对象,并且每个线程都尝试将其保存到数据库。

这是我的理论问题:

1) 我有一个具有属性(ssn、名称、地址)的 Person 对象。 2)三个线程都引用了这个person对象,每个线程都调用方法savePersonToHibernate(...)

public void savePersonToHibernate(Person person)
{
...
session.saveOrUpdate(person)
...
}

Hibernate 如何处理 3 个线程将同一个对象写入存储的情况?它是否将所有事务放入队列中,以便当第一个线程创建行和标识符(设置 id)时,其余两个线程只会更新它(在这种情况下)不进行任何更改?或者我实际上是否有机会在数据库中拥有 2 或 3 行,其中当前对象仅引用最后创建的标识符?

我希望它有一定的意义...我正在制作一个队列系统,数据需要引用需要动态创建的类别...如果两个或多个线程获取一些数据,而这些数据都需要创建相同的类别,我不想重复。

我希望这是有道理的......你会怎么做?

最佳答案

我假设所有提到的线程都使用不同的 session ,否则您会遇到麻烦,因为 hibernate session 不是线程安全的。

为了澄清这一点,如果所有三个线程都使用同一个 person 实例,并且这是一个新对象,那么您就会遇到麻烦,因为 hibernate 在访问或修改对象时不会执行任何同步。基本上每个线程的工作方式就好像其他线程不存在一样,因此每个线程都会首先检查 person 是否有非 null id,如果 id 为 null,则尝试生成它,然后将其分配给适当的实体字段。根据不同线程中检查-生成-分配的时间以及更改的可见性影响,并发创建的结果是不可预测的。

让我们看看如果所有线程都使用 person 的不同实例但具有相同的属性值会发生什么。在这种情况下,每个线程将尝试在数据库中创建三个不同的行,如果基础表没有唯一约束(例如唯一名称),它将成功。

您的类别创建特定场景实现起来并不是很简单。这个想法是尝试创建类别,但如果它已经存在则捕获异常。在后一种情况下,从数据库中读取现有类别并使用它。但请记住,条件插入的实现并不简单,并且可能依赖于 RDBMS。您可能会发现 PostgreSQL 的 upsert 操作稍微复杂一些但相关的示例和 SQL Server

关于java - Hibernate SaveOrUpdate - 多个工作线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19552597/

相关文章:

ruby-on-rails - 别名表名,以方便 3 列连接表(MySQL 或 PostgreSQL)

java - 如何在两种情况下都具有根元素的 Jersey 中获取 JSON 和 XML 响应?

java - Spring Boot ddl 自动生成器

.net - 适合特定情况的最佳基础设施

hibernate - JPA 双向关系的优缺点

java - 带有 spring-boot 和 DB2 数据库的 Java 应用程序的 SQL 结果限制

mysql - 具有分区 MySQL 表的 Hibernate 映射

Java修改ArrayList上的Class元素

java - 使用 Spring 以非 root 用户身份在端口 80 上启动 bootRun 进程

database - 如何对一对多关系进行唯一约束?