在我的应用程序中,我有一个记录锁定机制,可以防止两个人同时进入记录的编辑视图。以下是在编辑视图中调用记录时锁定记录的函数:
public function lockRecord($id = null) {
$this->loadModel('User');
$this->Model->id = $id;
$current = $this->Model->read(null, $id);
//Get the current logged-in user's ID
$userid = $current['Model']['requester_id'];
//Get the current lock expiry time
$lock_time = $this->Model->find('first', array(
'fields'=>array('Model.lock_expiry_time'),
'conditions'=>array('Model.id'=>$id)
)
);
//Get the ID of the user who has the record lock (if any)
$logged_user = $this->Model->find('first', array(
'fields'=>array('Model.lock_key'),
'conditions'=>array('Model.id'=>$id)
)
);
//Get that same user's full name
$full_name = $this->User->find('first', array(
'joins' => array(
array(
'table' => 'recordtable',
'alias' => 'Model',
'type' => 'INNER',
'conditions' => array('Model.lock_key = User.id')
)
)
)
);
$this->set('lock_time', $lock_time);
$this->set(compact($current));
$this->set(compact($logged_user));
$this->set(compact($full_name));
if(AuthComponent::user('id') != $logged_user['Msr']['lock_key'] && date("Y-m-d H:i:s") < $lock_time['Msr']['lock_expiry_time']) {
$this->Session->setFlash(__('This MSR is locked for editing by ' . $full_name['User']['full_name'] . '. Please try again in a few minutes or wait for this user to close the document.<br/>
(Lock expires at '. $lock_time['Msr']['lock_expiry_time'] . ')'));
$this->redirect(array('action' => 'view', $id));
} else {
//Set a new lock key and expiry time if the record is free for editing
$locksession = $this->Msr->query("UPDATE msrs SET lock_key = {$userid}, lock_expiry_time = ADDTIME(NOW(), '00:05:00') WHERE id = {$id}");
$this->set('locksession', $locksession);
}
}
当用户保存更改时,将调用unlockRecord函数以释放密钥,重置lock_expiry_time,并将用户重定向到&#34; View&#34;视图:
public function unlockRecord($id = null) {
//Get a list of security groups
$groups = $this->Session->read('groups');
$this->Msr->id = $id;
//Reset the lock_key and the lock_expiry_time
$locksession = $this->Msr->query("UPDATE msrs SET lock_key = '', lock_expiry_time = '' WHERE id = {$id} ");
//If the module admin manually releases the lock, display a message
if(in_array('msr_module_admin', $groups)) {
$this->Session->setFlash(__('The MSR has been unlocked and is available for editing.'));
}
$this->redirect(array('action'=>'view', $id));
}
还有其他三个可以释放锁定的条件:
- 管理员通过单击链接手动释放锁定。
- 用户完全退出系统。
- 锁定设置后五分钟到期。
我需要随时释放锁编辑视图中的记录不再有效。例如,如果用户点击其他网站或点击我自己网站中的其他链接;任何使他们远离他们在编辑视图中打开的记录的东西。 lock_key应设置为&#39;&#39;&#39;并将lock_expiry_time设置为&#39;&#39;。我怎么能做到这一点?
答案 0 :(得分:2)
认识到您的网站上的网页已被用户放弃,因此无法在网络编程中可靠地进行。
如果您关闭计算机/设备或断开网络连接,您的网站会发生什么变化?没有。如果她在编辑页面时单击书签栏中的链接会发生什么?没有。你再也没有收到她的消息。这就是你的锁具有到期时间的原因。
因此,要解决您的问题,您需要考虑缩短到期时间和/或减少页面放弃的可能性。
一种选择:在您的编辑页面中放置一些Javascript,每隔一段时间使用一次ajax-style请求,以便通过keepalive请求访问您的网站。您可以通过每分钟操作来访问您的网站。每次收到keepalive请求,您都可以将到期时间延长90秒。
另一个选择:你可能已经注意到StackOverflow页面会抛出一个浏览器对话框,上面写着“你想离开这个网站吗?”如果在编辑帖子时按BACK按钮。因此,每当您放弃页面时,实际上都会抛出对话框。他们在浏览器中使用onbeforeunload
事件。您也可以这样做,在激活编辑页面时启用对话框,并在用户保存时禁用它。
浏览器不允许网页在页面卸载时强制执行除对话框之外的任何操作。这样的功能对于网络蠕虫来说非常容易用来传播恶意软件。