阿江 2017-09-30 16:09:10 5364次浏览 0条回复 2 0 0

说明

学习Yii Framework 2易2框架的过程是漫长的也是充满乐趣的以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现提供了较完整的代码供你参考不妥之处请多多指正

原文网址:

http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#optimistic-locks
9、Optimistic Locks(乐观锁)

本文主题:AR乐观锁(Optimistic Locks)

9、乐观锁(Optimistic Locks)

当一条记录的数据被多个用户同时更新时,乐观锁是阻止这种冲突发生的一种方法。例如,用户A和B都在同时编辑同一篇wiki文章,在用户A保存他的内容时,用户B也在同时点击了"Save"按钮尝试保存他的内容。因为用户B实际上是在过期版本文章上进行操作,应该有一个好的方法阻止他存储文章,并给他一些提示信息。

乐观锁可以解决上面的问题,它使用一列为每一行数据记录下版本号,当一行数据使用过期版本号存储时,此行数据将不被存储,并抛出yii\db\StaleObjectException异常。只有当你使用yii\db\ActiveRecord::update()或yii\db\ActiveRecord::delete()更新或删除一条已存在的数据时,乐观锁才会生效。

使用乐观锁的步骤: 1)在数据表中添加一个字段与Active Record类相关联,此字段用于存储每行记录的版本号。此字段最好是整型(在MySQL中它将是BIGINT DEFAULT 0)。 2)重写yii\db\ActiveRecord::optimisticLock()方法返回此字段的名称。 3)在用户输入的Web表单中,添加一个隐藏字段去保存当前记录的版本信息。请确保版本信息有输入验证规则并验证成功。 4)在控制器使用Active Record更新记录数据的动作中,尝试和捕获yii\db\StaleObjectException异常,完成必要的业务逻辑(比如合并变化,提示过期信息)去解决这个冲突。

// ------ view code -------
use yii\helpers\Html;

// ...other input fields
echo Html::activeHiddenInput($model, 'version');

// ------ controller code -------
use yii\db\StaleObjectException;
public function actionUpdate($id)
{
    $model = $this->findModel($id);
    try {
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    } catch (StaleObjectException $e) {
        // logic to resolve the conflict
    }
}
MongoDB,实现乐观锁的实例:

//在视图中添加一个隐藏表单项

文件位置:
D:\phpwork\basic\views\country\_form.php
源代码:
<?= $form->field($model, 'rec_version')->hiddenInput()->label(false) ?>
文件位置:
D:\phpwork\basic\models\Country.php
源代码:
<?
//在模型中指定锁字段名称
	public function optimisticLock() {
        return 'rec_version';
    }
	public function rules() {
		return [
			//在model中要添加以下验证器:
			['rec_version','filter','filter'=>'intval'],
			/*
			此验证器有两个作用:
			1)新建记录时,给rec_version字段赋默认值0
			2)将表单中的rec_version转为整型,否则会在锁检测时报错:
			Stale Object Exception – yii\db\StaleObjectException
			The object being updated is outdated.
			*/
			......
		];
	}
	public function existRecVersion($attribute) {
		if(!$this->isNewRecord){
			$haveRec = static::findOne(['_id' =>$this->_id]);
			$optimisticLock=$this->optimisticLock();
			if($haveRec&&($haveRec[$optimisticLock]!=$this->$attribute)){
				$this->addError($attribute,"本条记录已被其他人修改过,请复制出本页面中您已修改过的重要信息后,再刷新页面重新编辑!");
			}
		}
	}

(全文完)

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册