Activiti5.22 ID到底是怎么生成的,每次都不一样,会不会有什么问题?

网络上查了一下,很多人发现activiti的id在不同情况下会造成id生成会重复。

上代码,先看看生成规则

引擎配置实现

ProcessEngineConfigurationImpl.initIdGenerator

  // id generator
  // /

  public void initIdGenerator() {
    if (idGenerator == null) {
      CommandExecutor idGeneratorCommandExecutor = null;
      if (idGeneratorDataSource != null) {
        ProcessEngineConfigurationImpl processEngineConfiguration = new StandaloneProcessEngineConfiguration();
        processEngineConfiguration.setDataSource(idGeneratorDataSource);
        processEngineConfiguration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_FALSE);
        processEngineConfiguration.init();
        idGeneratorCommandExecutor = processEngineConfiguration.getCommandExecutor();
      } else if (idGeneratorDataSourceJndiName != null) {
        ProcessEngineConfigurationImpl processEngineConfiguration = new StandaloneProcessEngineConfiguration();
        processEngineConfiguration.setDataSourceJndiName(idGeneratorDataSourceJndiName);
        processEngineConfiguration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_FALSE);
        processEngineConfiguration.init();
        idGeneratorCommandExecutor = processEngineConfiguration.getCommandExecutor();
      } else {
        idGeneratorCommandExecutor = getCommandExecutor();
      }

      DbIdGenerator dbIdGenerator = new DbIdGenerator();
      dbIdGenerator.setIdBlockSize(idBlockSize);
      dbIdGenerator.setCommandExecutor(idGeneratorCommandExecutor);
      dbIdGenerator.setCommandConfig(getDefaultCommandConfig().transactionRequiresNew());
      idGenerator = dbIdGenerator;
    }
  }

入口在

DbIdGenerator dbIdGenerator = new DbIdGenerator();
dbIdGenerator.setIdBlockSize(idBlockSize);

这段代码,采用DbIdGenerator的方式

再看源码

public class DbIdGenerator implements IdGenerator {

  protected int idBlockSize;
  protected long nextId;
  protected long lastId = -1;

  protected CommandExecutor commandExecutor;
  protected CommandConfig commandConfig;

  public synchronized String getNextId() {
    if (lastId < nextId) {
      getNewBlock();
    }
    long _nextId = nextId++;
    return Long.toString(_nextId);
  }

  protected synchronized void getNewBlock() {
    IdBlock idBlock = commandExecutor.execute(commandConfig, new GetNextIdBlockCmd(idBlockSize));
    this.nextId = idBlock.getNextId();
    this.lastId = idBlock.getLastId();
  }

  public int getIdBlockSize() {
    return idBlockSize;
  }

  public void setIdBlockSize(int idBlockSize) {
    this.idBlockSize = idBlockSize;
  }

  public CommandExecutor getCommandExecutor() {
    return commandExecutor;
  }

  public void setCommandExecutor(CommandExecutor commandExecutor) {
    this.commandExecutor = commandExecutor;
  }

  public CommandConfig getCommandConfig() {
    return commandConfig;
  }

  public void setCommandConfig(CommandConfig commandConfig) {
    this.commandConfig = commandConfig;
  }
}
getNextId()这里是每个业务记录生成id的方法
再看GetNextIdBlockCmd(idBlockSize)
public class GetNextIdBlockCmd implements Command<IdBlock> {

  private static final long serialVersionUID = 1L;
  protected int idBlockSize;

  public GetNextIdBlockCmd(int idBlockSize) {
    this.idBlockSize = idBlockSize;
  }

  public IdBlock execute(CommandContext commandContext) {
    PropertyEntity property = (PropertyEntity) commandContext.getPropertyEntityManager().findById("next.dbid");
    long oldValue = Long.parseLong(property.getValue());
    long newValue = oldValue + idBlockSize;
    property.setValue(Long.toString(newValue));
    return new IdBlock(oldValue, newValue - 1);
  }
}

每次从数据库中act_ge_property取出next.dbid计算出block的区间【min,max】

每个业务在获取id的时候通过getNextId 从当前ID值+1,id从区间的最小值开始;

那么ID为什么会重复呢,就是在idBlockSize这里,这个值是在代码中固化的2500,当流程中元素过多的时候会造成生成的id数量大于2500,就会造成id重复了,解决方案就是替换成uuid的生成方式,activiti已提供支持;

 

idBlockSize固化代码

public abstract class ProcessEngineConfiguration {

  /**
   * Checks the version of the DB schema against the library when the process engine is being created and throws an exception if the versions don't match.
   */
  public static final String DB_SCHEMA_UPDATE_FALSE = "false";

  /**
   * Creates the schema when the process engine is being created and drops the schema when the process engine is being closed.
   */
  public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";

  /**
   * Upon building of the process engine, a check is performed and an update of the schema is performed if it is necessary.
   */
  public static final String DB_SCHEMA_UPDATE_TRUE = "true";

  /** The tenant id indicating 'no tenant' */
  public static final String NO_TENANT_ID = "";

  protected String processEngineName = ProcessEngines.NAME_DEFAULT;
  protected int idBlockSize = 2500;
  protected String history = HistoryLevel.AUDIT.getKey();
  protected boolean asyncExecutorActivate;

以下是next.dbid 以40001 做为基数进行测试的id增长顺序

act_re_deployment 40001
act_ge_bytearray 40002 40003
act_re_procdef 40004

act_hi_identitylink 40005 40006 40009 40015 40016
act_hi_procinst 40007 40008 
act_hi_actinst 40010 40013
act_hi_varinst 40011 40012
act_ru_task 40014 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码者人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值