problem description
when recording audit logs, you need to generate a primary key by querying the largest primary key through sql and then + 1 as the primary key, but there is a primary key conflict problem. Now try to generate the log primary key id before inserting it as follows:
related codes
// service
@Service
public class AuditLogServiceImlp implements IAuditLogService{
public long nextId(String sysId){
return AuditLogIdIncrease.getInstance().nextId(sysId);
}
}
// id
public class AuditLogIdIncrease {
private static AuditLogIdIncrease instance;
private final int threadIdBits = 4;//
private final int maxRandomId = 9;//
private AuditLogIdIncrease() {
}
public static AuditLogIdIncrease getInstance() {
if (instance == null) {
instance = new AuditLogIdIncrease();
}
return instance;
}
/**
* ID
* @param sysId
* @return
*/
public synchronized long nextId(int sysId) {
return splice(sysId);
}
/**
* id:+++
* @param sysId
* @return
*/
private long splice(int sysId) {
String strLong = getCurrentTime() + getCurrentThreadId() + getRandomNum() + sysId;
return Long.parseLong(strLong);
}
/**
*
* @return
*/
private long getCurrentTime() {
return System.currentTimeMillis();
}
/**
*
* @return
*/
private String getCurrentThreadId() {
String strCurrentThreadId = String.format("%0" + threadIdBits + "d", Thread.currentThread().getId());
if (strCurrentThreadId.length() > threadIdBits) {
strCurrentThreadId = strCurrentThreadId.substring(0, threadIdBits);
}
return strCurrentThreadId;
}
/**
*
* @return
*/
private int getRandomNum() {
return new Random().nextInt(maxRandomId);
}
public static void main(String[] args) {
}
}
sources of topics and their own ideas
- make sure that AuditLogIdIncrease is a singleton
- AuditLogIdIncrease.nextId () is thread-safe
what result do you expect?
does this approach satisfy the unique (mainly singleton and thread-safe) design of getting id in concurrent situations? I wonder if it can be achieved through the Atomic class?