MDL-14992 pg session locking (8.2 and later only), refactoring and db session not default yet in new installs
This commit is contained in:
@@ -77,7 +77,7 @@ abstract class moodle_database {
|
||||
protected $last_type;
|
||||
protected $last_extrainfo;
|
||||
|
||||
protected $used_for_db_sessions = 0;
|
||||
protected $used_for_db_sessions = false;
|
||||
|
||||
/** internal temporary variable */
|
||||
private $fix_sql_params_i;
|
||||
@@ -98,13 +98,6 @@ abstract class moodle_database {
|
||||
$this->dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called only from session code!
|
||||
*/
|
||||
public function used_for_db_sessions() {
|
||||
$this->used_for_db_sessions = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if all needed PHP stuff installed.
|
||||
* Note: can be used before connect()
|
||||
@@ -254,7 +247,7 @@ abstract class moodle_database {
|
||||
if ($this->used_for_db_sessions) {
|
||||
// this is needed because we need to save session to db before closing it
|
||||
session_write_close();
|
||||
$this->used_for_db_sessions = 0;
|
||||
$this->used_for_db_sessions = false;
|
||||
}
|
||||
if ($this->database_manager) {
|
||||
$this->database_manager->dispose();
|
||||
@@ -1740,14 +1733,15 @@ abstract class moodle_database {
|
||||
}
|
||||
|
||||
/// session locking
|
||||
public function session_lock_supported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_session_lock($rowid) {
|
||||
// TODO: make this abstract
|
||||
return true;
|
||||
$this->used_for_db_sessions = true;
|
||||
}
|
||||
|
||||
public function release_session_lock($rowid) {
|
||||
// TODO: make this abstract
|
||||
return true;
|
||||
}
|
||||
|
||||
/// performance and logging
|
||||
|
||||
@@ -881,7 +881,12 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
}
|
||||
|
||||
/// session locking
|
||||
public function session_lock_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_session_lock($rowid) {
|
||||
parent::get_session_lock($rowid);
|
||||
$fullname = $this->dbname.'-'.$this->prefix.'-session-'.$rowid;
|
||||
$sql = "SELECT GET_LOCK('$fullname',120)";
|
||||
$this->query_start($sql, null, SQL_QUERY_AUX);
|
||||
@@ -893,17 +898,16 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
$result->close();
|
||||
|
||||
if (reset($arr) == 1) {
|
||||
return true;
|
||||
return;
|
||||
} else {
|
||||
// try again!
|
||||
return $this->get_session_lock($rowid);
|
||||
$this->get_session_lock($rowid);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function release_session_lock($rowid) {
|
||||
parent::release_session_lock($rowid);
|
||||
$fullname = $this->dbname.'-'.$this->prefix.'-session-'.$rowid;
|
||||
$sql = "SELECT RELEASE_LOCK('$fullname')";
|
||||
$this->query_start($sql, null, SQL_QUERY_AUX);
|
||||
@@ -911,15 +915,8 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
$this->query_end($result);
|
||||
|
||||
if ($result) {
|
||||
$arr = $result->fetch_assoc();
|
||||
$result->close();
|
||||
|
||||
if (reset($arr) == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// transactions
|
||||
|
||||
@@ -1047,6 +1047,46 @@ class pgsql_native_moodle_database extends moodle_database {
|
||||
return $positivematch ? '~*' : '!~*';
|
||||
}
|
||||
|
||||
/// session locking
|
||||
public function session_lock_supported() {
|
||||
return $this->is_min_version('8.2.0');
|
||||
}
|
||||
|
||||
public function get_session_lock($rowid) {
|
||||
// TODO: there is a potential locking problem for database running
|
||||
// multiple instances of moodle, we could try to use pg_advisory_lock(int, int),
|
||||
// luckily there is not a big chance that they would collide
|
||||
if (!$this->session_lock_supported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::get_session_lock($rowid);
|
||||
$sql = "SELECT pg_advisory_lock($rowid)";
|
||||
$this->query_start($sql, null, SQL_QUERY_AUX);
|
||||
$result = pg_query($this->pgsql, $sql);
|
||||
$this->query_end($result);
|
||||
|
||||
if ($result) {
|
||||
pg_free_result($result);
|
||||
}
|
||||
}
|
||||
|
||||
public function release_session_lock($rowid) {
|
||||
if (!$this->session_lock_supported()) {
|
||||
return;
|
||||
}
|
||||
parent::release_session_lock($rowid);
|
||||
|
||||
$sql = "SELECT pg_advisory_unlock($rowid)";
|
||||
$this->query_start($sql, null, SQL_QUERY_AUX);
|
||||
$result = pg_query($this->pgsql, $sql);
|
||||
$this->query_end($result);
|
||||
|
||||
if ($result) {
|
||||
pg_free_result($result);
|
||||
}
|
||||
}
|
||||
|
||||
/// transactions
|
||||
/**
|
||||
* on DBs that support it, switch to transaction mode and begin a transaction
|
||||
|
||||
+3
-4
@@ -5,7 +5,7 @@
|
||||
* @return moodle_session
|
||||
*/
|
||||
function session_get_instance() {
|
||||
global $CFG;
|
||||
global $CFG, $DB;
|
||||
|
||||
static $session = null;
|
||||
|
||||
@@ -18,7 +18,8 @@ function session_get_instance() {
|
||||
$session_class = SESSION_CUSTOM;
|
||||
$session = new $session_class();
|
||||
|
||||
} else if (!isset($CFG->dbsessions) or $CFG->dbsessions) {
|
||||
//} else if ((!isset($CFG->dbsessions) or $CFG->dbsessions) and $DB->session_lock_supported()) {
|
||||
} else if (!empty($CFG->dbsessions) and $DB->session_lock_supported()) {
|
||||
// default recommended session type
|
||||
$session = new database_session();
|
||||
|
||||
@@ -299,8 +300,6 @@ class database_session extends session_stub {
|
||||
global $DB;
|
||||
|
||||
$this->database = $DB;
|
||||
$this->database->used_for_db_sessions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user