Class yii\behaviors\OptimisticLockBehavior
OptimisticLockBehavior 自动地根据列名更新模型的锁版本(译者注:请读者自行查阅乐观锁的知识体系), 列名是通过 optimisticLock() 读取的。
乐观锁机制允许多个用户对同一条记录进行更新并避免潜在的冲突。 比如当用户试图保存含有脏数据的记录(因为另一个用户已经更新过该条记录)时, 将会抛出 \yii\behaviors\StaleObjectException 异常, 这样更新或者删除操作就会跳过。
要使用该行为,首先通过列在 optimisticLock() 方法注释里的几步来开启乐观锁验证机制,然后从你的 rules() 方法里清除掉存有锁版本的列, 最后给你的 ActiveRecord 类添加下面的代码:
use yii\behaviors\OptimisticLockBehavior;
public function behaviors()
{
return [
OptimisticLockBehavior::className(),
];
}
默认情况下,OptimisticLockBehavior 会从 getBodyParam() 中解析 提交过来的版本值或者在失败时设置为0。这意味着一个没有携带表示乐观锁版本值的请求也许可以在第一次成功更新该实体, 但自那以后任何更多地请求都应该失败,直到这个请求携带了期望的版本号, 才可以最终更新成功。
该行为一旦附加到模型类中,如果 getBodyParam() 中没有携带版本值, 那么模型类的内部操作比如在保存记录时就会失败。它在扩展模型类上非常有用, 通过覆盖父类的 optimisticLock() 方法来开启乐观锁, 然后附加行为到子类中,这样可以把携带行为的子类关联到接收并处理终端用户输入数据的控制器的同时, 也可以把子类绑定到父类的内部逻辑处理中, 或者你也可以把 $value 属性配置为 PHP 回调函数来实现不同的逻辑。
OptimisticLockBehavior 也提供了一个名为 upgrade() 的方法来给模型的版本值加一, 当多个客户端连接出现的情况下,你需要主动标记某实体为脏数据时该方法将非常有用。 这样可以在客户端最终加载该实体之前避免任何更新:
$model->upgrade();
参见 yii\db\BaseActiveRecord::optimisticLock() 详情来参考如何开启乐观锁。.
公共属性
属性 | 类型 | 描述 | 被定义在 |
---|---|---|---|
$attributes | array | 属性列表,属性的值将由 $value 自动填充。
数组的键是 ActiveRecord 的事件,属性就是更新于这些事件之上,
数组的值就是要更新的属性。
你可以用字符串来表示一个单独的属性也可以用一个数组来表示一系列属性。比如,
` php
[
ActiveRecord::EVENT_BEFORE_INSERT => ['attribute1', 'attribute2'],
ActiveRecord::EVENT_BEFORE_UPDATE => 'attribute2',
]
` |
yii\behaviors\AttributeBehavior |
$owner | yii\base\Component|null | The owner of this behavior | yii\base\Behavior |
$preserveNonEmptyValues | boolean | 是否保留非空的属性值 | yii\behaviors\AttributeBehavior |
$skipUpdateOnClean | boolean | 当 $owner
没有更新的时候是否跳过这个行为 |
yii\behaviors\OptimisticLockBehavior |
$value | mixed | 要分配给当前属性的值。它可以是一个匿名函数,
数组格式的 callable(比如 [$this, 'methodName'] ),一个 Expression 对象表示的 DB 表达式
(比如 new Expression('NOW()') ),标量,字符串或者一个任意的值。
如果是前者,函数的返回值将会设置给这些属性。
函数的签名应该像下面这样,
` php
function ($event)
{
// 返回值将会设置到当前的属性
}
` |
yii\behaviors\OptimisticLockBehavior |
公共方法
方法 | 描述 | 被定义在 |
---|---|---|
__call() | Calls the named method which is not a class method. | yii\base\BaseObject |
__construct() | Constructor. | yii\base\BaseObject |
__get() | Returns the value of an object property. | yii\base\BaseObject |
__isset() | Checks if a property is set, i.e. defined and not null. | yii\base\BaseObject |
__set() | Sets value of an object property. | yii\base\BaseObject |
__unset() | Sets an object property to null. | yii\base\BaseObject |
attach() | Attaches the behavior object to the component. | yii\behaviors\OptimisticLockBehavior |
canGetProperty() | Returns a value indicating whether a property can be read. | yii\base\BaseObject |
canSetProperty() | Returns a value indicating whether a property can be set. | yii\base\BaseObject |
className() | Returns the fully qualified name of this class. | yii\base\BaseObject |
detach() | Detaches the behavior object from the component. | yii\base\Behavior |
evaluateAttributes() | 计算属性的值并分配给当前属性。 | yii\behaviors\AttributeBehavior |
events() | Declares event handlers for the $owner's events. | yii\behaviors\OptimisticLockBehavior |
hasMethod() | Returns a value indicating whether a method is defined. | yii\base\BaseObject |
hasProperty() | Returns a value indicating whether a property is defined. | yii\base\BaseObject |
init() | Initializes the object. | yii\base\BaseObject |
upgrade() | 主动更新版本值进行加一操作,然后存入数据库中。 | yii\behaviors\OptimisticLockBehavior |
受保护的方法
方法 | 描述 | 被定义在 |
---|---|---|
getLockAttribute() | 返回保存版本值的列名,该列名在 optimisticLock() 中定义。 | yii\behaviors\OptimisticLockBehavior |
getValue() | 返回给当前属性准备的值。 该方法在 evaluateAttributes() 里调用。 它的返回值将会设置到对应触发事件的属性上。 | yii\behaviors\OptimisticLockBehavior |
属性详情
当 $owner
没有更新的时候是否跳过这个行为
如果是 null
它将直接从 getBodyParam() 中解析或者解析失败时设置为 0。
要分配给当前属性的值。它可以是一个匿名函数,
数组格式的 callable(比如 [$this, 'methodName']
),一个 Expression 对象表示的 DB 表达式
(比如 new Expression('NOW()')
),标量,字符串或者一个任意的值。
如果是前者,函数的返回值将会设置给这些属性。
函数的签名应该像下面这样,
function ($event)
{
// 返回值将会设置到当前的属性
}
方法详情
Attaches the behavior object to the component.
The default implementation will set the $owner property and attach event handlers as declared in events(). Make sure you call the parent implementation if you override this method.
public void attach($owner) | ||
$owner | yii\base\Component | The component that this behavior is to be attached to. |
Declares event handlers for the $owner's events.
Child classes may override this method to declare what PHP callbacks should be attached to the events of the $owner component.
The callbacks will be attached to the $owner's events when the behavior is attached to the owner; and they will be detached from the events when the behavior is detached from the component.
The callbacks can be any of the following:
- method in this behavior:
'handleClick'
, equivalent to[$this, 'handleClick']
- object method:
[$object, 'handleClick']
- static method:
['Page', 'handleClick']
- anonymous function:
function ($event) { ... }
The following is an example:
[
Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
]
public array events() | ||
return | array | Events (array keys) and the corresponding event handler methods (array values). |
---|
返回保存版本值的列名,该列名在 optimisticLock() 中定义。
protected string getLockAttribute() | ||
return | string | 属性名。 |
---|---|---|
throws | yii\base\InvalidCallException | 如果 optimisticLock() 配置有误时。 |
返回给当前属性准备的值。 该方法在 evaluateAttributes() 里调用。 它的返回值将会设置到对应触发事件的属性上。
如果是 null
,版本值将直接从 getBodyParam() 中解析或者解析失败时设置为 0。
protected mixed getValue($event) | ||
$event | yii\base\Event | 触发当前属性更新的事件 |
return | mixed | 属性值 |
---|
主动更新版本值进行加一操作,然后存入数据库中。
$model->upgrade();
public void upgrade() | ||
throws | yii\base\InvalidCallException | 如果属主是一条新记录时。 |
---|