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;
$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()
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();
}
/// 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
}
/// 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);
$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);
$this->query_end($result);
if ($result) {
- $arr = $result->fetch_assoc();
$result->close();
-
- if (reset($arr) == 1) {
- return true;
- }
}
-
- return false;
}
/// transactions
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
* @return moodle_session
*/
function session_get_instance() {
- global $CFG;
+ global $CFG, $DB;
static $session = null;
$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();
global $DB;
$this->database = $DB;
- $this->database->used_for_db_sessions();
-
return true;
}