mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge pull request #5717 from cakephp/2.7-session-concurrency
2.7 session concurrency
This commit is contained in:
commit
4113eb0db4
2 changed files with 66 additions and 1 deletions
|
@ -103,6 +103,9 @@ class DatabaseSession implements CakeSessionHandlerInterface {
|
|||
/**
|
||||
* Helper function called on write for database sessions.
|
||||
*
|
||||
* Will retry, once, if the save triggers a PDOException which
|
||||
* can happen if a race condition is encountered
|
||||
*
|
||||
* @param int $id ID that uniquely identifies session in database
|
||||
* @param mixed $data The value of the data to be saved.
|
||||
* @return bool True for successful write, false otherwise.
|
||||
|
@ -114,7 +117,17 @@ class DatabaseSession implements CakeSessionHandlerInterface {
|
|||
$expires = time() + $this->_timeout;
|
||||
$record = compact('id', 'data', 'expires');
|
||||
$record[$this->_model->primaryKey] = $id;
|
||||
return $this->_model->save($record);
|
||||
|
||||
$options = array(
|
||||
'validate' => false,
|
||||
'callbacks' => false,
|
||||
'counterCache' => false
|
||||
);
|
||||
try {
|
||||
return $this->_model->save($record, $options);
|
||||
} catch (PDOException $e) {
|
||||
return $this->_model->save($record, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -191,4 +191,56 @@ class DatabaseSessionTest extends CakeTestCase {
|
|||
$storage->gc();
|
||||
$this->assertFalse($storage->read('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* testConcurrentInsert
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConcurrentInsert() {
|
||||
$this->skipIf(
|
||||
$this->db instanceof Sqlite,
|
||||
'Sqlite does not throw exceptions when attempting to insert a duplicate primary key'
|
||||
);
|
||||
|
||||
ClassRegistry::removeObject('Session');
|
||||
|
||||
$mockedModel = $this->getMockForModel(
|
||||
'SessionTestModel',
|
||||
array('exists'),
|
||||
array('alias' => 'MockedSessionTestModel', 'table' => 'sessions')
|
||||
);
|
||||
Configure::write('Session.handler.model', 'MockedSessionTestModel');
|
||||
|
||||
$counter = 0;
|
||||
// First save
|
||||
$mockedModel->expects($this->at($counter++))
|
||||
->method('exists')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
// Second save
|
||||
$mockedModel->expects($this->at($counter++))
|
||||
->method('exists')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
// Second save retry
|
||||
$mockedModel->expects($this->at($counter++))
|
||||
->method('exists')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// Datasource exists check
|
||||
$mockedModel->expects($this->at($counter++))
|
||||
->method('exists')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$this->storage = new DatabaseSession();
|
||||
|
||||
$this->storage->write('foo', 'Some value');
|
||||
$return = $this->storage->read('foo');
|
||||
$this->assertSame('Some value', $return);
|
||||
|
||||
$this->storage->write('foo', 'Some other value');
|
||||
$return = $this->storage->read('foo');
|
||||
$this->assertSame('Some other value', $return);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue