How to generate unique ID by java using pre-allocation method
Editor to share with you how java uses the pre-allocation method to generate a unique ID, I believe most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!
There is often a business requirement to generate a unique ID in a project. As a unique identification to facilitate follow-up search and tracking. There are also many implementation schemes on the Internet. For example: database self-increasing primary key, database batch generation ID,UUID, timestamp method, zookeeper generation ID,redis generation unique ID,snowflake algorithm and so on. These solutions have their own advantages and disadvantages. The solution I often use in game projects is to generate a unique ID by pre-allocation. Its principle is simple, easy to expand, and has strong applicability.
The pre-allocation method generates a unique ID principle: the last pre-allocated dbUniqueID value of each type is stored in the database. Add the currently allocated
UseDbUniqueId . The pre-allocated step size DBUNIQUEID_M can be customized according to the type and traffic volume. When useDbUniqueId is greater than or equal to dbUniqueId, DBUNIQUEID_M unique ID is pre-allocated.
Role ID generation: a 7-bit consecutive unique ID is required. Then DBUNIQUEID_M=1. 1000000+dbUniqueId is formatted into 7 digits.
This service only ID: then DBUNIQUEID_M=10000. (1000000+dbUniqueId) * 10000+serverId formatted. ServerId game suit ID is defined as 4 digits.
Globally unique ID: then DBUNIQUEID_M=10000. ((100000000000L+dbUniqueId) 100 formatted gameCode 10000 workerID; formatted. The gameCode game code is defined as 2 bits.
For specific implementation, please refer to the code. It is very convenient to transplant to the project project.
IdWorkerEnum.java
Package com.game.common.db;import java.util.List;import com.core.enums.LLIndexedEnum / * ID enumerated type * @ author Thinker * / public enum IdWorkerEnum implements LLIndexedEnum {/ * role ID * / IDWORKER_HUMANID (1, "role ID"), / * * database ID * / IDWORKER_DBID (2, "database ID"), / * * union ID * / IDWORKER_CLUBID (3, "union ID"), / * * collect ID * / IDWORKER_COLLECTID (4, "collect ID") / * enumerated index * / public final int index; / * key * / private final String nameKey; / * * enumerated array * / private static final List indexes=LLIndexedEnum.IndexedEnumUtil.toIndexes (IdWorkerEnum.values ()) stored in indexed order; private IdWorkerEnum (int index,String nameKey) {this.index=index; this.nameKey=nameKey } / * get index * / @ Override public int getIndex () {return index;} / * get the name key * / public String getNameKey () {return this.nameKey } / * get the definition of enumerations according to the specified index * / public static IdWorkerEnum valueOf (final int index) {return LLIndexedEnum.IndexedEnumUtil.valueOf (indexes,index);}}
DbUniqueIdEntity.java
Package com.game.common.db;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;import org.eclipse.persistence.annotations.HashPartitioning;import org.eclipse.persistence.annotations.Partitioned;import com.game.common.db.dao.BaseDbBean / * * Database unique KEY entity class * @ author Thinker * / @ Entity (name= "t_dbUniqueId") @ HashPartitioning (name= "HashPartitionByDbUniqueCacheId", partitionColumn=@Column (name= "dbUniqueCacheId")) @ Partitioned ("HashPartitionByDbUniqueCacheId") public class DbUniqueIdEntity extends BaseDbBean {/ * * Database unique cache ID * / @ Id @ Column (length=20) private long dbUniqueCacheId; / * * Database unique ID * / @ Column (length=20) private long dbUniqueId / * * Last updated time * * / @ Column (length=20) private long createTime; / / Internal data / / * * unique ID (unique ID) of the database that has been used * / @ Column (length=20) private long useDbUniqueId; @ Override public long getId () {return dbUniqueCacheId } @ Override public void setId (long id) {} public long getDbUniqueCacheId () {return dbUniqueCacheId;} public void setDbUniqueCacheId (long dbUniqueCacheId) {this.dbUniqueCacheId=dbUniqueCacheId;} public long getDbUniqueId () {return dbUniqueId;} public void setDbUniqueId (long dbUniqueId) {this.dbUniqueId=dbUniqueId;} public long getCreateTime () {return createTime } public void setCreateTime (long createTime) {this.createTime=createTime;} public long getUseDbUniqueId () {return useDbUniqueId;} public void setUseDbUniqueId (long useDbUniqueId) {this.useDbUniqueId=useDbUniqueId;}}
IdWorker.java
Package com.game.common.db;import com.game.common.Globals;import com.game.common.entityProxy.EntityProxy;import com.game.core.appConfig.AppConfigServ;import com.game.core.utils.LoggerUtils;/** * unique ID generator * * @ author Thinker * / public class IdWorker {public final static IdWorker OBJ=new IdWorker (AppConfigServ.OBJ.getAppConfigBean (). GetServerNo ()); private int DBUNIQUEID_M=2000; private final long workerId / * * Database connection pool * / private DbUniqueIdEntity [] szDbUniqueIdEntity=new DbUniqueIdEntity [5]; public IdWorker (long workerId) {this.workerId=workerId;} / * Generation system unique ID: implicit lock mode * / public synchronized long nextId () {IdWorkerEnum idWorkerEnum=IdWorkerEnum.IDWORKER_DBID; int dbUniqueCacheId=idWorkerEnum.getIndex (); loadDbUniqueId (idWorkerEnum); DbUniqueIdEntity dbUniqueIdEntity=szDbUniqueIdEntity [dbUniqueCacheId] Long dbUniqueId=0; / / need to reassign Id: each allocation of M if (dbUniqueIdEntity.getUseDbUniqueId () > = dbUniqueIdEntity.getDbUniqueId ()) {dbUniqueIdEntity.setDbUniqueId (dbUniqueIdEntity.getDbUniqueId () + DBUNIQUEID_M); EntityProxy.OBJ.update ((long) dbUniqueCacheId,dbUniqueIdEntity); LoggerUtils.serverLogger.info ("IdWorker DbId:update dbUniqueId=" + dbUniqueIdEntity.getDbUniqueId ());} dbUniqueId=dbUniqueIdEntity.getUseDbUniqueId () + 1 DbUniqueIdEntity.setUseDbUniqueId (dbUniqueId); / / 11-bit UUID return (1000000+dbUniqueId) * 10000 workerId;} / * unique HumanID of the generation system: implicit lock mode * / public synchronized long nextHumanId () {IdWorkerEnum idWorkerEnum=IdWorkerEnum.IDWORKER_HUMANID; int dbUniqueCacheId=idWorkerEnum.getIndex (); loadDbUniqueId (idWorkerEnum); DbUniqueIdEntity dbUniqueIdEntity=szDbUniqueIdEntity [dbUniqueCacheId]; long dbUniqueId=0 / / need to reassign Id: each allocation of M if (dbUniqueIdEntity.getUseDbUniqueId () > = dbUniqueIdEntity.getDbUniqueId ()) {dbUniqueIdEntity.setDbUniqueId (dbUniqueIdEntity.getDbUniqueId () + 1); EntityProxy.OBJ.update ((long) dbUniqueCacheId,dbUniqueIdEntity); LoggerUtils.serverLogger.info ("IdWorker HumanId:update dbUniqueId=" + dbUniqueIdEntity.getDbUniqueId ());} dbUniqueId=dbUniqueIdEntity.getUseDbUniqueId () + 1 DbUniqueIdEntity.setUseDbUniqueId (dbUniqueId); / / 7-bit UUID return (1000000+dbUniqueId);} / * * unique ClubID of the generation system: implicit lock mode * / public synchronized long nextClubId () {IdWorkerEnum idWorkerEnum=IdWorkerEnum.IDWORKER_CLUBID; int dbUniqueCacheId=idWorkerEnum.getIndex (); loadDbUniqueId (idWorkerEnum); DbUniqueIdEntity dbUniqueIdEntity=szDbUniqueIdEntity [dbUniqueCacheId]; long dbUniqueId=0 / / need to reassign Id: each allocation of M if (dbUniqueIdEntity.getUseDbUniqueId () > = dbUniqueIdEntity.getDbUniqueId ()) {dbUniqueIdEntity.setDbUniqueId (dbUniqueIdEntity.getDbUniqueId () + 1); EntityProxy.OBJ.update ((long) dbUniqueCacheId,dbUniqueIdEntity); LoggerUtils.serverLogger.info ("IdWorker clubId:update dbUniqueId=" + dbUniqueIdEntity.getDbUniqueId ());} dbUniqueId=dbUniqueIdEntity.getUseDbUniqueId () + 1 DbUniqueIdEntity.setUseDbUniqueId (dbUniqueId); / / 5-bit UUID return (10000+dbUniqueId);} / * * unique ID of the generation system: implicit lock mode * / public synchronized long nextCollectId () {IdWorkerEnum idWorkerEnum=IdWorkerEnum.IDWORKER_COLLECTID; int dbUniqueCacheId=idWorkerEnum.getIndex (); loadDbUniqueId (idWorkerEnum); DbUniqueIdEntity dbUniqueIdEntity=szDbUniqueIdEntity [dbUniqueCacheId]; long dbUniqueId=0 / / need to reassign Id: each allocation of M if (dbUniqueIdEntity.getUseDbUniqueId () > = dbUniqueIdEntity.getDbUniqueId ()) {dbUniqueIdEntity.setDbUniqueId (dbUniqueIdEntity.getDbUniqueId () + DBUNIQUEID_M); EntityProxy.OBJ.update ((long) dbUniqueCacheId,dbUniqueIdEntity); LoggerUtils.serverLogger.info ("IdWorker DbId:update dbUniqueId=" + dbUniqueIdEntity.getDbUniqueId ());} dbUniqueId=dbUniqueIdEntity.getUseDbUniqueId () + 1 DbUniqueIdEntity.setUseDbUniqueId (dbUniqueId); / / 18-bit UUID: game ID+ server ID. Make sure that ID with multiple games and no repetition is supported. It is easy to be compatible with statistics return ((100000000000L+dbUniqueId) * 100+AppConfigServ.OBJ.getAppConfigBean (). GetGameCode ()) * 10000 workerId;} / * load unique ID * / public void loadDbUniqueId (IdWorkerEnum idWorkerEnum) {int dbUniqueCacheId=idWorkerEnum.getIndex (); if (szDbUniqueIdEntity [dbUniqueCacheId]! = null) return; DbUniqueIdEntity dbUniqueIdEntity=EntityProxy.OBJ.get ((long) dbUniqueCacheId, (long) dbUniqueCacheId,DbUniqueIdEntity.class) If (dbUniqueIdEntity==null) {dbUniqueIdEntity=new DbUniqueIdEntity (); dbUniqueIdEntity.setDbUniqueCacheId (dbUniqueCacheId); dbUniqueIdEntity.setDbUniqueId (0); dbUniqueIdEntity.setCreateTime (Globals.getTimeService (). Now ()); dbUniqueIdEntity.setUseDbUniqueId (0); EntityProxy.OBJ.insert ((long) dbUniqueCacheId,dbUniqueIdEntity);} dbUniqueIdEntity.setUseDbUniqueId (dbUniqueIdEntity.getDbUniqueId ()) SzDbUniqueIdEntity [dbUniqueCacheId] = dbUniqueIdEntity; LoggerUtils.serverLogger.info ("IdWorker:load dbUniqueId=" + dbUniqueIdEntity.getDbUniqueId ());}} above is all the content of the article "how to generate a unique ID by java using pre-allocation method". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!