首页 > 解决方案 > 多线程中的休眠@GeneratedValue序列

问题描述

我有 2 个主要实体 Dog 和 Cat 他们都有不同的字段,除了iddataVersion
id 字段不是由hibernate数据库生成的。
该字段dataVersion是使用@GeneratedValue相同的数据库序列生成的。

问题是这样的,我有 2 个线程:

  1. 线程 1 创建实体Dog将其持久化,然后休眠 30 秒
  2. 线程 2 在线程 1 之后 10 秒启动,线程 2 持久化实体Cat并提交它。
  3. 线程 1 在 30 秒后提交

我期望数据库拥有的是Dog具有 dataVersion 2 的实体Cat和具有 dataVersion 1 的实体,但不知何故,实体Dog具有 dataVersion 1 而实体Cat具有 dataVersion 2 。

我在互联网上搜索了allot,@GeneratedValue发现值是在刷新事务时生成的,所以我关闭了自动刷新。只有在提交事务并且我仍然没有得到预期的结果时才会发生刷新。

我想知道这个问题的原因是什么。


@Entity
@Getter
@Setter
public class Dog {
    @Id
    private String id;

    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "dataVersionGen")
    @SequenceGenerator(name = "dataVersionGen", sequenceName = "DATA_VER_SEQ")
    private Long dataVersion;
}

@Entity
@Getter
@Setter
public class Cat {
    @Id
    private String id;

    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "dataVersionGen")
    @SequenceGenerator(name = "dataVersionGen", sequenceName = "DATA_VER_SEQ")
    private Long dataVersion;
}

这是开始运行时评估的代码

@Component
public class Example {
    private ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    @Autowired
    private DBAccessor accessor;

    @PostConstruct
    public void example() {
        threadPoolTaskExecutor.initialize();

        // Starts dog's thread
        threadPoolTaskExecutor.execute(() -> {
            Dog dog = new Dog();
            dog.setId(UUID.randomUUID().toString());

            accessor.persist(dog);

            sleep(30 * SECOND);

            accessor.commit();
        });

       // Starts dog's thread
        threadPoolTaskExecutor.execute(() -> {
            sleep(10 * SECOND);

            Cat cat = new Cat();
            cat.setId(UUID.randomUUID().toString());

            accessor.persist(cat);
            accessor.commit();
        });
    }
}

标签: javamultithreadinghibernatejpaspring-data-jpa

解决方案


持久性提供者可以随时生成 ID,只要它遵守规范(即,只要实体最终在数据库中具有唯一 ID)。

您不应该假设 ID 是在刷新时生成的,因为情况并非如此。

而且您不应该关心猫的 ID 是否比狗的 ID 低或高:重要的是 ID 是唯一的。


推荐阅读