Spring Boot 锁定代码以获取唯一 id [英] Spring Boot locking code to get an unique id

查看:25
本文介绍了Spring Boot 锁定代码以获取唯一 id的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个控制器,它必须返回一个唯一的字符串.要求是此控制器的两次调用永远不会返回相同的字符串,即使经过多年,即使代码将扩展到更多 VM.

I wrote a controller that must return an unique String. The requirement is that two calling of this controller never return the same String, even after years and even if the code will scale to more VMs.

我的问题是以下代码对于实现声明的目的是否正确,或者您是否有任何提示.

My question is if the following code is correct to achieve to declared purpose, or if you have any hint.

控制器:

@RestController
public class UtilityController {

    @Autowired
    UtilityServices utilityServices;

    @GetMapping("/uniqueIdentifier")
    @ResponseBody
    public String uniqueIdentifier() {
        return utilityServices.getUniqueIdentifier();
    }

服务:

@Service
public class UtilityServices {

    @Autowired
    private UniqueIdRepository uniqueIdRepository;

    @Transactional
    public String getUniqueIdentifier() {
       String uniqueId = RandomString.getSecureRandomString();
       while (uniqueIdRepository.existsById(uniqueId)) {
           uniqueId = RandomString.getSecureRandomString();
       }
       uniqueIdRepository.save(new UniqueId(uniqueId));
       return uniqueId;
    }
}

实体:

@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
@ToString
public class UniqueId implements Serializable {

    @Id
    private String uniqueId;   

}

存储库:

public interface UniqueIdRepository extends CrudRepository<UniqueId, String> {

}

仅此而已.我省略了 RandomString 类的代码,因为它在此上下文中不相关:我基于 SecureRandom 编写了一个代码,很可能每次它返回一个不同的字符串,但我对此没有任何保证.让我们假设我的 RandomString.getSecureRandomString() 方法迟早会返回相同的字符串.

That's all. I omit the code the RandomString class because it's not relevant in this context: I wrote a code based on SecureRandom, it is very likely that each time it returns a different String, but I have no guarantees about it. Let's assume that sooner or later my RandomString.getSecureRandomString() method can return the same String.

我不确定 @Transactional 注释是否保证 getUniqueIdentifier() 方法永远不会抛出错误.

I'm not sure if the @Transactional annotation guarantees that the getUniqueIdentifier() method never throws an error.

推荐答案

在您的情况下更好的主意是使用 UUID:

The much better idea at your case will be using UUID:

因此,任何人都可以创建一个 UUID 并使用它来标识某些东西,几乎可以肯定的是,该标识符不会与已经或将要创建的标识符重复以标识其他东西.因此,独立方标有 UUID 的信息可以稍后合并到单个数据库中或在同一频道上传输,重复的可能性可以忽略不计.

Thus, anyone can create a UUID and use it to identify something with near certainty that the identifier does not duplicate one that has already been, or will be, created to identify something else. Information labelled with UUIDs by independent parties can, therefore, be later combined into a single database or transmitted on the same channel, with a negligible probability of duplication.

@Service
public class UtilityServices {
    @Autowired
    private UniqueIdRepository uniqueIdRepository;

    @Transactional
    public String getUniqueIdentifier() {
       String uniqueId = String.format("%s-%s",
            RandomStringUtils.randomAlphanumeric(4),
            UUID.randomUUID().toString().replace("-", "")
       );
       // you could left this check 
       while (uniqueIdRepository.existsById(uniqueId)) {
           uniqueId = UUID.randomUUID().toString().replace("-", "");
       }
       uniqueIdRepository.save(new UniqueId(uniqueId));
       return uniqueId;
    }
}

顺便说一句你可以使用 @Data 作为模型:

BTW you could use @Data for Model:

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class UniqueId implements Serializable {
    private static final long serialVersionUID = 0L;
    @Id
    private String uniqueId;   
}

不要忘记 serialVersionUID.

有用的参考:

这篇关于Spring Boot 锁定代码以获取唯一 id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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