Instant now = Instant.now(); // 获取当前时间 long currentTimeMillis = now.toEpochMilli(); // 作为主键id可能存在重复,怎么解决
时间: 2024-09-25 17:05:16 浏览: 32
System.currentTimeMillis()计算方式与时间的单位转换详解
5星 · 资源好评率100%
`Instant.now().toEpochMilli()` 返回的是自 Unix 纪元 (1970年1月1日) 起经过的毫秒数,这确实可能导致数据库中的主键(通常是唯一标识符)冲突,尤其是在高并发环境下。为了解决这个问题,有几种常见策略:
1. **时间戳加序列号**:结合当前时间戳与本地生成的唯一序列号(如 UUID 或自增整数),形成一个复合键。
```java
UUID uuid = UUID.randomUUID();
long sequence = generateUniqueId(); // 自定义生成唯一序列
long uniqueId = currentTimeMillis + uuid.getMostSignificantBits() << 32 | sequence;
```
2. **使用时间戳的微秒或纳秒**:由于纳秒级别的差异更小,理论上更不可能重复,但数据库需要支持这种精度。
```java
long nanoTimeId = now.getNano();
```
3. **使用数据库提供的解决方案**:许多现代数据库提供原子的、基于时间的唯一ID生成机制,比如MySQL的`TIMESTAMP WITH TIME ZONE AUTO_INCREMENT` 或者 PostgreSQL 的 `SERIAL` 和 `uuid-ossp` 插件等。
4. **使用乐观锁定**:如果插入操作失败(如尝试插入已存在的ID),则回滚事务并再次尝试,直到成功。但这会增加数据库的开销。
每种方法都有其优缺点,选择哪种取决于你的具体需求、数据库支持以及应用程序的设计。建议先评估业务场景再做决策。
阅读全文