【问题标题】:The resulting GUID is duplicated, is my java code error?生成的 GUID 重复,是我的 java 代码错误吗?
【发布时间】:2018-12-21 14:13:04
【问题描述】:

根据我在网上查到的资料,GUID重复的概率很小,那么是不是我的代码有问题?

public class AccountTaskExecutorTask extends TimerTask {
    private static final Logger logger = Logger.getLogger(AccountTaskExecutorTask.class);
    private TellerDbCore.AccountTask.Builder aTask = null;

    public AccountTaskExecutorTask(TellerDbCore.AccountTask.Builder aTask) {
        this.aTask = aTask;
    }

    public static void schedule(TellerDbCore.AccountTask.Builder aTask) {
        Timer timer = new Timer();
        timer.schedule(new AccountTaskExecutorTask(aTask), 100L);
    }

    @Override
    public void run() {
        try {
            DataBaseStore dataBaseStore = null;
            try {
                dataBaseStore = DbHelper.getTransactableDbStore();
                invest(aTask, dataBaseStore);
                dataBaseStore.commitAndClose();
                dataBaseStore = null;
            } catch (Exception e) {
                logger.error("", e);
                if (dataBaseStore != null) {
                    dataBaseStore.rollbackAndClose();
                    dataBaseStore = null;
                }
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }


    private static void invest(TellerDbCore.AccountTask.Builder theTask, DataBaseStore dataBaseStore) throws Exception {
            switch (theTask.getTaskStatus()) {
                case TS_READY:
                    List<TellerDbCore.AccountSubTask.Builder> subList = AccountTaskHelper.querySubAtByMtId(theTask.getTaskId(), dataBaseStore);
                    if (subList.size() == 0) {
                        NewMethods.newAccountSubTask(theTask.getTaskId(), GUID.generateGUID().toLowerCase(),
                                theTask.getAccountId(), theTask.getProductType(), theTask.getTaskType(), theTask.getAmount(), dataBaseStore);
                    }
                    UpdateMethods.updateAccountTask(theTask.getTaskId(), null, BtsDbBase.TaskStatus.TS_PROCESSING, dataBaseStore);
                    break;
                case TS_PROCESSING:
                    break;
                case TS_SUCCESSED:
                case TS_FAILED:
                    break;
                default:
                    logger.info( theTask.getTaskStatus());
                    break;
            }
    }
}

在此代码中,GUID 由GUID.generateGUID().toLowerCase() 生成,包的名称为oscore-2.2.4.jarNewMethods.newAccountSubTask是向数据库中添加数据。

这是GUID的代码

package com.opensymphony.util;

import com.opensymphony.module.random.Yarrow;
import java.math.BigInteger;

public final class GUID
{
  private static Yarrow rnd = new Yarrow();

  public static String generateFormattedGUID()
  {
    String guid = generateGUID();

    return guid.substring(0, 8) + '-' + guid.substring(8, 12) + '-' + guid.substring(12, 16) + '-' + guid.substring(16, 20) + '-' + guid.substring(20);
  }

  public static String generateGUID()
  {
    return new BigInteger(165, rnd).toString(36).toUpperCase();
  }
}

【问题讨论】:

  • GUID 类/接口是什么...?
  • GUID 是类。
  • 那你的错误是什么?
  • 为什么不使用“java.util.UUID”?
  • 你能用UUID.randomUUID();吗?

标签: java guid


【解决方案1】:

假设 GUID 的潜在值的数量是 n,一个非常大的自然数。我们还假设已经选择的值的数量是 k。现在,值重复的概率 (p) 取决于 n 和 k。 n 是一个非常大的自然数,但让我们看看 k 的可能值(我假设所有可能的值具有大致相同的概率):

k == 0

在这种情况下,您将获得第一个 GUID,并且不可能获得重复。 p == 0

k === n

在这种情况下,您已经拥有所有可能的值,并且不可能没有重复。 p == 1

0

在这种情况下,获得新值的概率为:

p == (n - k) / n

因为我们需要排除已经选择的 k 个元素。另一方面,得到重复的概率是

p' == k / n

所以随着k的增加,p减小而p'增加。请注意,前两种情况是这种一般情况的特殊情况。现在,有什么办法可以避免重复?

好吧,您使用的是小写字母,这基本上将可能的值减少了一半。如果您避免使用小写字母,则 n 实际上会翻倍。此外,您可以为新值使用两个连接的 guid 值,因为它们的字符串长度不同,所以它们永远不会与您以前使用的值重复。或者,您可以在 gui 字符串之前使用 id。

【讨论】:

    猜你喜欢
    • 2019-09-24
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2017-08-16
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    相关资源
    最近更新 更多