Yii2 ActiveRecord添加具有唯一文本字段的新记录

时间:2017-04-04 12:57:27

标签: yii2 yii2-model

我正在使用Yii2和ActiveRecord。我有一个名为" code"并且对于每个记录,它意味着具有如下的唯一值:" REC0001"," REC0002"," REC0003"以顺序的方式。

一切正常,我可以按照描述生成记录代码。但是,如果我以多种方式快速刷新页面请求(尝试以非常原始的方式同时测试多个请求),那么一些记录最终会得到相同的记录代码。换句话说,我发现" REC007"几次。

我生成代码查看最后一个代码并将其增加一个,然后通过检查它是否已经存在于数据库中来执行findFlag == true。

我怀疑写入数据库有延迟,因此假设它不存在。

以下是代码的一部分:

static function createCode($rec){
    if ($rec->code){
        return $rec->code;
    }
    if ($rec->id){ // find it by id if one passed and record exists
        $tmpRec = $rec->find()
            ->where([
                'id'  => $rec->id,
            ])
            ->one();
        if ($tmpRec && $tmpRec->code){
            return $tmpRec->code;
        }
    }

    $prefix = 'REC';
    if (!$prefix){
        $prefix = 'REC';
    }
    $maxDecimals = 12;
    $codeLength = $maxDecimals+strlen($prefix);
    $query = $rec->find();
    $query = $query->where([
        'archived'  => '0'
    ]);

    // look under an organization if it exists in the model and there is one
    if ($rec->hasField('organization_id') && $organization_id){
        $query = addQueryWhere($query, [
            'organization_id'   => $organization_id,
        ]);
    }
    $query = addQueryWhere($query, [
        'LENGTH(code)'   => $codeLength*1,
    ]);
    $query = $query->orderBy('code desc');

    $lastRec = $query->one();

    $tmpNumber = 0;
    if ($lastRec && $lastRec->id){
        // check what it returns
        $tmpNumber = str_replace($prefix, '', $lastRec->code);
    }

    $tmpNumber++;
    $leftDecimals = $maxDecimals - strlen($tmpNumber.'');
    for ($k=0; $k <= $leftDecimals-1 ; $k++){
        $tmpNumber = '0'. $tmpNumber;
    }
    $ret = $prefix . $tmpNumber;
    return $ret;
}
public function generateCode($rec){
    $foundFlag = true;
    $break = 1000; // safe break point - no continuous loop
    $cnt = 0;
    $code = static::createCode($rec);
    while ($foundFlag === true || $cnt < $break){
        $tmpRec = $rec->find()
            ->where([
                'code'  => $code,
            ])
            ->one();
        if (!$tmpRec->id){
            $foundFlag = false;
            break;
        }
        $time = getCurrentTimestamp();
        $code = static::createCode($rec);
        $cnt++;
    }
    $ret = $code;
    return $ret;
}

所以我只需拨打:$ this-&gt; code = $ this-&gt; generateCode(); 就像我说的那样,它确实可以生成代码,但是当它不应该生成时会产生重复!

感谢您的协助。

0 个答案:

没有答案