【问题标题】:Doctrine2, retry insert with different value on duplicate keyDoctrine2,在重复键上重试插入不同的值
【发布时间】:2013-07-25 07:25:17
【问题描述】:

我正在尝试创建某个哈希值。遵循以下路径:

  1. 使用 $hash 上的唯一键创建一些哈希对象
  2. 构造函数填充种子以生成实际的 $hash
  3. 尝试保存
  4. 如果由于错误 23000(重复键)而导致保存失败,请创建一个不同的散列并重复,直到创建一个尚不存在的唯一散列。

现在这是我的问题。使用 Doctrine2,当查询由于 SQL 错误而失败时,它会关闭 EntityManager。就我而言,这没问题,因为我会重试。

如果哈希值已经存在,一个解决方案是搜索数据库。由于碰撞(md5)的数量非常非常少,并且需要尽快完成工作(我可以节省的每一毫秒都是值得的),我想跳过检查。

我认为值得一试的另一个解决方案是clone 实体管理器。但是,在内部,实体管理器已经传递给内部的对象,它们没有被克隆,而是与引用一起传递。

第三种解决方案是使用注册表并创建一个新的实体管理器。但是,在这个对象之外,我将没有正确的实体管理器:

  • 对象 A 获取 EM -> 进行查询
  • 对象 B 获取 EM -> 查询 > 错误 > 创建新 EM
  • 对象 C 获取 EM -> 使用新 EM 进行查询
  • 对象 A > 查询 > 错误,已关闭,因为在步骤 1 中已获取。

我应该怎么做才能快速插入?我需要通过实体来完成,我不会进行平面 DQL/SQL 查询。

【问题讨论】:

    标签: doctrine-orm entity flush duplicates


    【解决方案1】:

    如何在持久化之前找到一个唯一的哈希?

    do {
        $unique_hash = md5(microtime()); // Work out your hash here.
        $existing = $repository->findOneByHash($unique_hash);
        if (!$existing) {
            break; // else carry on until we get one.
        }
    } while (1);
    
    // Use your unique hash here.
    

    【讨论】:

    • 这是我目前的实现。然而,正如已经提到的,这太慢了。假设执行此选择需要 3 毫秒。这意味着超过 200000 次哈希生成,我的脚本将花费 600000 毫秒,即 10 分钟。这意味着我的批次将运行 25 分钟,而不是每小时运行 15 分钟。
    • 也许将所有哈希值放入一个 PHP 数组中,然后使用 in_array 而不是一次在数据库中循环遍历该数组?每次发生冲突时重新打开实体管理器会更慢。
    猜你喜欢
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    相关资源
    最近更新 更多