Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/236.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CakePHP中的数据并发管理-行为/控制器/模型?_Php_Mysql_Concurrency_Cakephp 2.3 - Fatal编程技术网

CakePHP中的数据并发管理-行为/控制器/模型?

CakePHP中的数据并发管理-行为/控制器/模型?,php,mysql,concurrency,cakephp-2.3,Php,Mysql,Concurrency,Cakephp 2.3,为了管理并发性(即确保保存到数据库中的数据不过时或已被其他用户编辑),在我的CakePHP应用程序中,我在编辑函数中使用了modified属性。下面是我的控制器中的代码片段 $this->MyModel->recursive = -1; $event = $this->MyModel->findById($id); $requestTimeStamp = new DateTime($this->request->data['MyModel']['modifie

为了管理并发性(即确保保存到数据库中的数据不过时或已被其他用户编辑),在我的CakePHP应用程序中,我在编辑函数中使用了
modified
属性。下面是我的控制器中的代码片段

$this->MyModel->recursive = -1;
$event = $this->MyModel->findById($id);
$requestTimeStamp = new DateTime($this->request->data['MyModel']['modified']);
$dbTimeStamp = new DateTime($event['MyModel']['modified']);
if ($requestTimeStamp < $dbTimeStamp) {
    $response = array(
         'success' => false, 
         'id' => $id, 
         'message' => 'A concurrency error occurred while trying to save. Please try again');
    echo json_encode($response);
    exit;
} else {
   //... continue processing
}
$this->MyModel->recursive=-1;
$event=$this->MyModel->findById($id);
$requestTimeStamp=newdatetime($this->request->data['MyModel']['modified']);
$dbTimeStamp=newdatetime($event['MyModel']['modified']);
如果($requestTimeStamp<$dbTimeStamp){
$response=array(
“成功”=>错误,
'id'=>$id,
'消息'=>'尝试保存时发生并发错误。请重试';
echo json_编码($response);
出口
}否则{
//…继续处理
}
这段代码工作得很好——但当我试图在我的应用程序中对其进行优化时,我正试图找出最好的位置。它最好放在我的
AppModel
类中,还是最好为它创建
行为
,还是最好放在控制器中?我认为一个理想的选择将考虑性能和最小化类加载开销以及数据库访问开销。p>
以前有人遇到过/解决过这个问题吗?感谢您的想法/建议。

因此我通过将并发检查作为我的
AppModel->beforeSave()方法的一部分来解决这个问题。以下代码供其他人参考

/*
 * Incorporated concurrency check in the beforeSave callback method to ensure that data is not stale before user saves.
 * The function checks if the model has a `modified` field, before it proceeds. If the model does not have such a method
 * then concurrency does not apply to this data structure. Upon proceeding, the method checks to see if the value of modified
 * data is the same in the database as well as the request that invokes this method. If they are not same then the save is 
 * aborted
 * This method requires the view or controller to pass a variable called data[ModelName][modified]. 
 * This variable must contain the value of the modified field when the record was read and it must be passed back as such. 
 * I usually set a hidden form field in my view like below - 
 * <input type="hidden" name="data[Model][modified]" value="<?php echo $model['modifed']; ?>" />
 */
    public function beforeSave($options = array()) {
        if ($this->hasField('modified') && isset($this->data[$this->name]['id']) && isset($this->data[$this->name]['modified'])) {
            CakeLog::debug('AppModel: beforeSave - inside concurrency check');
            CakeLog::debug($this->data);
            $this->recursive = -1;

            // run a select statement to ensure the modified date in the database has not changed. If it has changed then 
            // the below find query will return 0 rows
            $row = $this->find('first', array(
                'fields' => array(
                    'id', 'modified'
                ),
                'conditions' => array(
                    'id' => $this->data[$this->name]['id'],
                    'modified' => $this->data[$this->name]['modified']
                )
            ));

            // if no row is returned then error out and return - basically a concurrency error has occurred
            if (!$row) {
                CakeLog::error($this->name.':Concurrency error - [row-id:'.$this->data[$this->name]['id'].']');
                return false;
            }

            // if a row was retrned then there is no concurrency error, so proceed but change the modified date
            // to current timestamp to reflect accuracy
            $this->data[$this->name]['modified'] = date('Y-m-d H:i:s');
            return true;
        }
    }
/*
*在beforeSave回调方法中合并了并发检查,以确保在用户保存之前数据不会过时。
*在继续之前,该函数检查模型是否有“modified”字段。如果模型没有这样的方法
*那么并发性不适用于此数据结构。继续后,该方法将检查
*数据库中的数据与调用此方法的请求中的数据相同。如果它们不相同,则保存为
*流产
*此方法要求视图或控制器传递名为data[ModelName][modified]的变量。
*读取记录时,此变量必须包含已修改字段的值,并且必须将其传回。
*我通常在视图中设置一个隐藏的表单字段,如下所示-
*