在负载平衡期间,如何在多个springmvc应用程序实例之间通过ValueGenerator维护在JPA实体中生成的唯一密钥

问题描述

我有一个jpa实体,该实体已经具有一个生成为uuid的ID,并且还需要一个唯一的人类可读ID。所以我用ValueGenerator生成一个ref_key。

@Id@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2",strategy = "uuid2")
@Type(type = "uuid-char")@Column(name="ID")
private UUID id;

@GeneratorType(type = UniqueIdGenerator.class,when = GenerationTime.INSERT)
@Column(name = "REF_KEY",updatable = false,insertable = true,unique = true,nullable = false)
private String refKey;

为了生成此唯一的ref_key,我使用了时间戳和一个简单的计数器。代码在下面

public class UniqueIdGenerator implements ValueGenerator {

    private static volatile String lastTimestamp = "";
    private static volatile int counter = 1;
    private String valuePrefix = "UNI_";

    @Override
    public String generateValue(Session session,Object owner) {
        return generateUniqueId(valuePrefix);
    }

    private static synchronized String generateUniqueId(String prefix) {
        String id;
        Date dNow = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyMMdd_HHmmss");
        String datetimeId = ft.format(dNow);
        if (lastTimestamp.equalsIgnoreCase(datetimeId)) {
            id = prefix + datetimeId + "_" + counter;
            counter++;
        } else {
            id = prefix + datetimeId;
            counter = 1;
        }
        lastTimestamp = datetimeId;
        return id;
    }
}

所有这些都可以在一个实例上正常工作。但是正在为此应用程序部署多个实例以实现负载平衡,因此很可能会在同一时刻生成相同的ID并将其插入DB中。如何避免在数据库中出现重复项?有什么更好的方法

DB使用Oracle 11g。

在采用这种方法之前,我尝试了几种不同的方法,例如从DB端使用序列,但没有成功,整个模型/实体部分被单独打包,因此无法从此部分访问DB。可以执行其他操作以根据实例生成唯一的计数器值并将其插入到DB中。请帮忙。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)